File: gnat_examples.py

package info (click to toggle)
gnat-gps 18-5
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 45,716 kB
  • sloc: ada: 362,679; python: 31,031; xml: 9,597; makefile: 1,030; ansic: 917; sh: 264; java: 17
file content (127 lines) | stat: -rw-r--r-- 4,728 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import glob
import os
import os_utils
import re
import distutils.dir_util
import GPS
from modules import Module


class ExampleAction(GPS.Action):

    def __init__(self, example_name, directory, gpr_file, readme):
        """ Create an action to load one example in GPS.

            example_name is the name to use for the example,
            directory is the directory containing the expample project,
            gpr_file is the project file to load, and
            readme (if any) the file to edit after project load.
        """
        GPS.Action.__init__(self, 'open example ' + example_name)
        self.gpr_file = gpr_file
        self.readme = readme
        self.example_name = example_name
        self.directory = directory
        self.create(self.on_activate, filter='', category='Help',
                    description='Load project for example ' + example_name)

    def on_activate(self):
        """ Activate the action.

            Ask the user for a destination directory and copy all the files
            contained in the example project's directory in it.
            Load the copied project file and display the README, if any.
        """

        new_proj_dir = str(GPS.MDI.directory_selector())

        distutils.dir_util.copy_tree(self.directory, new_proj_dir)

        new_gpr_file = os.path.join(
            new_proj_dir, os.path.basename(self.gpr_file))
        GPS.Project.load(new_gpr_file)

        if self.readme:
            new_readme_file = os.path.join(
                    new_proj_dir, os.path.basename(self.readme))
            GPS.EditorBuffer.get(GPS.File(new_readme_file))


class GNATExamples(Module):

    def _process_examples_dir(self, submenu_name, example_directory):
        """ Process a directory and place any valid examples found there.

            example_directory is the directory in which to look for examples
            submenu_name is the name of the menu to create beneath
              Help/GNAT
        """

        actions = []
        title_regexp = re.compile('<title>GNAT \&prefix;(.+)</title>')

        for subdir in (glob.glob(os.path.join(example_directory, '*')) +
                       glob.glob(os.path.join(example_directory, '*', '*'))):
            gprs = glob.glob(os.path.join(subdir, '*.gpr'))
            if len(gprs) == 1:
                # There is only one GPR file in this project: we can
                # create the action that opens this.

                # Find the readme
                readmes = glob.glob(os.path.join(subdir, 'README*'))
                readme = None
                if readmes:
                    readme = readmes[0]

                # Find the name of the action, attempting to read it in the
                # xml file
                name = os.path.basename(subdir)
                xmlfile = os.path.join(subdir, name + '.xml')
                if os.path.isfile(xmlfile):
                    with open(xmlfile, 'r') as f:
                        matches = title_regexp.findall(f.read())
                        if len(matches) == 1:
                            name = matches[0]
                actions.append(
                    ExampleAction(name, subdir, gprs[0], readme)
                )
        # sort the actions, and create the menus
        actions.sort(key=lambda x: x.example_name)

        ref_menu = ''
        for a in actions:
            menu_name = "/Help/GNAT/Examples/{}/{}".format(
                submenu_name, a.example_name)
            a.menu(menu_name, ref_menu)
            ref_menu = menu_name

    def _populate_menu(self):
        """ Populate the Help menu with the GNAT examples """

        # For now, we look for the location of "gnat" from the PATH.
        # TODO: get the path from toolchains, if any (this requires
        # exposing the toolchains API to Python, or providing another
        # high-level service).

        # Create the native examples menu, if any
        if "gnat" not in self.menus_created_for_compiler:
            self.menus_created_for_compiler.append("gnat")

            gnat = os_utils.locate_exec_on_path("gnat")
            examples_root = os.path.join(
                os.path.dirname(gnat), "..", "share", "examples", "gnat"
            )
            self._process_examples_dir("Native", examples_root)

        # TODO: support cross gnat. Right now the examples that ship with
        # the cross compilers require massaging with a Makefile, and therefore
        # are not suited to GPS integration.

    def setup(self):
        self.menus_created_for_compiler = []
        # The list of menu paths that have already been created

        self._populate_menu()

    def project_view_changed(self):
        self._populate_menu()