diff --git a/.travis.yml b/.travis.yml index 6192987fc..c341fcf26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,6 @@ env: matrix: include: - env: RUNTIME=3.6 TOOLKITS="null pyqt5 pyside2 wx" - - os: osx - env: RUNTIME=3.6 TOOLKITS="null pyqt5 pyside2 wx" cache: directories: diff --git a/CHANGES.rst b/CHANGES.rst index 5a736c49d..c40868cfc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,10 +7,12 @@ Version 5.0.0 Released: XXXX-XX-XX -This is a major release mainly relating to code modernization. In this -release, support for Python versions <3.6 have been dropped. The +This is a major release mainly relating to code modernization. In this +release, support for Python versions <3.6 have been dropped. The class_load_hooks and single_project modules have been removed. Additionally, -there were various fixes to bugs, examples, tests, and documentation. +there were various fixes to bugs, examples, tests, and documentation. Demo +examples are also distributed as package data such that they are visible via +the "etsdemo" GUI application (to be installed separately). Features -------- @@ -22,6 +24,7 @@ Features Fixes ----- +- Fix index slice in ExtensionPointChangedEvent when plugin changes (#357) - Fix ValueError from unregistering services when application stops (#345) - Fix the MOTD example (#319) - Fix the Hello_World example (#318) @@ -31,6 +34,9 @@ Fixes Documentation ------------- +- Contribute examples to etsdemo (#380) +- Refactor documentation links to source on GitHub (#379) +- Make example run from any directory (#377) - Setup intersphinx in docs (#343) - Add documentation for envisage APIs (#340) - Use jinja templates for API documentation (#339) @@ -63,6 +69,7 @@ Tests Build ----- +- Turn off macOS builds on Travis CI (#375) - Fix CI cron job setup to install apptools (#348) - Update setup.py to allow prerelease version (#344) - Add wx as being supported in etstool, add it back to CI, and test against diff --git a/docs/source/conf.py b/docs/source/conf.py index 8bda425b0..a3c7ab6c9 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -33,6 +33,7 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ "sphinx.ext.autodoc", + "sphinx.ext.extlinks", "sphinx.ext.githubpages", "sphinx.ext.intersphinx", "sphinx.ext.napoleon", @@ -85,6 +86,39 @@ # output. They are ignored by default. # show_authors = False +# Substitutions reusable for all files. + +rst_epilog = """ +.. + # substitutions for API objects + +.. |Application| replace:: :class:`~envisage.application.Application` +.. |IApplication| replace:: :class:`~envisage.i_application.IApplication` +.. |ExtensionPoint| replace:: :class:`~envisage.extension_point.ExtensionPoint` +.. |Plugin| replace:: :class:`~envisage.plugin.Plugin` +.. |IPlugin| replace:: :class:`~envisage.i_plugin.IPlugin` +.. |envisage.api| replace:: :mod:`envisage.api` +.. |envisage.ui.workbench| replace:: :mod:`envisage.ui.workbench.api` + +.. + # substitutions for the Hello World example + +.. |Hello World| replace:: :github-demo:`Hello World ` + +.. + # substitutions for MOTD examples + +.. |acme.motd| replace:: :github-demo:`acme.motd ` +.. |acme.motd.software_quotes| replace:: :github-demo:`acme.motd.software_quotes ` +.. |MOTD| replace:: :github-demo:`MOTD ` +.. |IMOTD| replace:: :github-demo:`IMOTD ` +.. |MOTDPlugin| replace:: :github-demo:`MOTDPlugin ` +.. |MOTD run| replace:: :github-demo:`run.py ` +.. |IMessage| replace:: :github-demo:`IMessage ` +.. |Message| replace:: :github-demo:`Message ` +.. |messages.py| replace:: :github-demo:`message.py ` +.. |Message of the Day| replace:: :github-demo:`Message of the Day ` +""" # noqa: E501 # Options for HTML output # ----------------------- @@ -193,3 +227,12 @@ "traits": ("https://docs.enthought.com/traits", None), "traitsui": ("https://docs.enthought.com/traitsui", None), } + + +# -- Options for extlinks extension ------------------------------------------- + +extlinks = { + 'github-demo': ( + 'https://github.com/enthought/envisage/tree/master/envisage/examples/demo/%s', # noqa: E501 + '') +} diff --git a/docs/source/envisage_core_documentation/extension_points.rst b/docs/source/envisage_core_documentation/extension_points.rst index 4ecb6da47..3f2f53ef0 100644 --- a/docs/source/envisage_core_documentation/extension_points.rst +++ b/docs/source/envisage_core_documentation/extension_points.rst @@ -2,7 +2,7 @@ Extension Points ================ Whether or not we as software developers like to admit it, most (if not all) of -the applications we write need to change over time. We fix bugs, and we add, +the applications we write need to change over time. We fix bugs, and we add, modify, and remove features. In other words, we spend most of our time either fixing or extending applications. @@ -14,7 +14,7 @@ mechanism at each one. This makes it hard for developers who want to extend the application to know a) *where* they can add extensions, and b) *how* to add them. -Envisage attempts to address this problem by admitting up front that +Envisage attempts to address this problem by admitting up front that applications need to be extensible, and by providing a standard way for developers to advertise the places where extension can occur (known as *extension points*), and for other developers to contribute *extensions* to @@ -22,7 +22,7 @@ them. In Envisage, extension points and the extensions contributed to them are stored in the *extension registry*. To see how extension points actually work, let's -take a look at the `Message of the Day`_ example included in the Envisage +take a look at the |Message of the Day| example included in the Envisage distribution. This example shows how to build a very simple application that prints a (hopefully witty, educational, or inspiring) "Message of the Day" chosen at random from a list of contributed messages. @@ -32,12 +32,12 @@ Declaring an Extension Point Plugins declare their extension points in one of two ways: -1) Declaratively - using the 'ExtensionPoint' trait type +1) Declaratively - using the |ExtensionPoint| trait type 2) Programmatically - by overriding the 'get_extension_points' method. -In the MOTD example, the acme.motd_ plugin needs to advertise an extension +In the MOTD example, the |acme.motd| plugin needs to advertise an extension point that allows other plugins to contribute new messages. Using the -'ExtensionPoint' trait type, the plugin would look like this:: +|ExtensionPoint| trait type, the plugin would look like this:: class MOTDPlugin(Plugin): """ The MOTD Plugin. """" @@ -84,25 +84,25 @@ Either way, this tells us three things about the extension point: 1) That the extension point is called "acme.motd.messages" 2) That every item in a list of contributions to the extension point must - implement the IMessage_ interface. + implement the |IMessage| interface. 3) That the extension point allows you to contribute messages! Making contributions to an Extension Point ------------------------------------------ -The `Message of the Day`_ example has a second plugin, -acme.motd.software_quotes_ that contributes some pithy quotes about software +The |Message of the Day| example has a second plugin, +|acme.motd.software_quotes| that contributes some pithy quotes about software development to the application. First of all, we have to create the messages that we want to add. Remember that -when the acme.motd_ plugin advertised the extension point, it told us that -every contribution had to implement the IMessage_ interface. Happily, there is -a class that does just that already defined for us (Message_) and so we create -a simple module (messages.py_) and add our Message_ instances to it:: +when the |acme.motd| plugin advertised the extension point, it told us that +every contribution had to implement the |IMessage| interface. Happily, there is +a class that does just that already defined for us (|Message|) and so we create +a simple module (|messages.py|) and add our |Message| instances to it:: messages = [ ... - + Message( author = "Martin Fowler", text = "Any fool can write code that a computer can understand. Good" @@ -118,7 +118,7 @@ a simple module (messages.py_) and add our Message_ instances to it:: ... ] -Now we create a plugin for the acme.motd.software_quotes_ package and tell +Now we create a plugin for the |acme.motd.software_quotes| package and tell Envisage about the messages that we have just created. Again there are are two ways that a plugin can do this: @@ -186,14 +186,14 @@ event. Retrieving the contributions to an Extension Point -------------------------------------------------- -OK, here's where we are so far: One plugin (acme.motd_) has advertised the fact +OK, here's where we are so far: One plugin (|acme.motd|) has advertised the fact that it has an extension point called "acme.motd.messages", and that the -contributions to the extension point must implement the IMessage_ interface. -Another plugin (acme.motd.software_quotes_) has kindly offered to contribute +contributions to the extension point must implement the |IMessage| interface. +Another plugin (|acme.motd.software_quotes|) has kindly offered to contribute some messages about software development. Now we need to know how to retrieve the contributed messages at runtime. -In the MOTD example, the messages are retrieved by the acme.motd_ plugin:: +In the MOTD example, the messages are retrieved by the |acme.motd| plugin:: class MOTDPlugin(Plugin): """ The MOTD Plugin. """" @@ -223,15 +223,15 @@ In the MOTD example, the messages are retrieved by the acme.motd_ plugin:: ... As you can see, all we have to do is to access the **messages** extension point -trait when we create our instance of the MOTD_ class. +trait when we create our instance of the |MOTD| class. This example demonstrates a common pattern in Envisage application development, in that contributions to extension points are most often used by plugin implementations to create and initialize services (in this case, an instance of -the MOTD_ class). +the |MOTD| class). The extension registry can also be accessed through the following method on the -IApplication_ interface:: +|IApplication| interface:: def get_extensions(self, extension_point): """ Return a list containing all contributions to an extension point. @@ -245,31 +245,11 @@ extension point you would use:: messages = application.get_extensions('acme.motd.messages') -Note however, that using the ExtensionPoint_ trait type, adds the ability to +Note however, that using the |ExtensionPoint| trait type, adds the ability to validate the contributions -- in this case, to make sure that they are all -objects that implement (or can be adapted to) the IMessage_ interface. It also +objects that implement (or can be adapted to) the |IMessage| interface. It also automatically connects the trait so that the plugin will receive trait change events if extensions are added/removed to/from the extension point at runtime. .. _`Python Eggs`: http://peak.telecommunity.com/DevCenter/PythonEggs - -.. _acme.motd: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/motd_plugin.py - -.. _acme.motd.software_quotes: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/software_quotes/software_quotes_plugin.py - -.. _ExtensionPoint: https://github.com/enthought/envisage/tree/master/envisage/extension_point.py - -.. _IApplication: https://github.com/enthought/envisage/tree/master/envisage/i_application.py - -.. _IMessage: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/i_message.py - -.. _Message: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/message.py - -.. _messages.py: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/software_quotes/messages.py - -.. _`Message of the Day`: https://github.com/enthought/envisage/tree/master/examples/MOTD - -.. _MOTD: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/motd.py - -.. _MOTDPlugin: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/motd_plugin.py diff --git a/docs/source/envisage_core_documentation/introduction.rst b/docs/source/envisage_core_documentation/introduction.rst index 4712ce16f..8dd004dc4 100644 --- a/docs/source/envisage_core_documentation/introduction.rst +++ b/docs/source/envisage_core_documentation/introduction.rst @@ -10,7 +10,7 @@ The project is really divided into 3 sub-projects:- 1) Core_ - The Envisage Core, found in the top-level envisage_ package, + The Envisage Core, found in the top-level |envisage.api| package, defines the basic application architecture including the plugin and extension mechanisms. All of the other sub-projects are simply collections of plugins that are built on top of the core. @@ -23,7 +23,7 @@ The project is really divided into 3 sub-projects:- functionality commonly required in this type of application including actions, menubars, toolbars, user preferences, wizards etc. One of the most useful plugins in this project is the Workbench_ plugin (found in the - envisage.ui.workbench_ package) that helps you build a style of + |envisage.ui.workbench| package) that helps you build a style of user interface that is often (but not exclusively) found in integrated development environments (IDEs). @@ -49,7 +49,7 @@ Getting Started --------------- The best way to get started is probably to take the time to read and digest the -Core_ documentation and then work through the `Hello World`_ and +Core_ documentation and then work through the |Hello World| and `Message of the Day`_ examples. Despite being extremely simple, the examples introduce you to *all* of the fundamental concepts of Envisage, and the *real* applications that you build (which will hopefully be a lot more useful) will be @@ -67,9 +67,3 @@ documentation and examples first). .. _NetBeans: http://www.netbeans.org .. _OSGi: http://www.osgi.org .. _Workbench: Workbench.html - -.. _`Hello World`: https://github.com/enthought/envisage/tree/master/examples/Hello_World/hello_world.py - -.. _envisage: https://github.com/enthought/envisage/tree/master/envisage/api.py - -.. _envisage.ui.workbench: https://github.com/enthought/envisage/tree/master/envisage/ui/workbench/api.py diff --git a/docs/source/envisage_core_documentation/message_of_the_day.rst b/docs/source/envisage_core_documentation/message_of_the_day.rst index 2555abadc..cdb02222f 100644 --- a/docs/source/envisage_core_documentation/message_of_the_day.rst +++ b/docs/source/envisage_core_documentation/message_of_the_day.rst @@ -9,12 +9,12 @@ the rare applications that is so simple that why would you bother), but it does serve to illustrate all of the fundamental aspects of building an Envisage application. -All of the code for this example can be found in the `examples/MOTD`_ directory -of the Envisage distribution, and to run it simply type:: +All of the code for this example can be found in the |Message of the Day| +directory of the Envisage distribution, and to run it simply type:: cd .../examples/MOTD python run.py - + (or equivalent, depending on your operating system and shell) Before we dive right in to building our extensible application, let's take a @@ -29,38 +29,38 @@ Plain Ol' MOTD -------------- So lets take a look at our non-Envisage aware MOTD application, the code for -which is in the acme.motd_ package. A good place to start as a developer +which is in the |acme.motd| package. A good place to start as a developer *using* any package in Envisage (and, for that matter, the entire Enthought tool-suite) is to look at any interfaces and classes exposed via its 'api.py' module. In this case, there are 2 interfaces -1) IMOTD_ +1) |IMOTD| - The interface for simple "Message of the Day" functionality. + The interface for simple "Message of the Day" functionality. -2) IMessage_ +2) |IMessage| - The interface supported by each message returned by the motd() method on - the IMOTD_ interface. + The interface supported by each message returned by the motd() method on + the |IMOTD| interface. We also (*not* coincidentally!) have 2 corresponding implementation classes: -1) MOTD_ -2) Message_ +1) |MOTD| +2) |Message| -As you can see, the MOTD_ class simply contains a list of messages and +As you can see, the |MOTD| class simply contains a list of messages and when its motd() method is called, it returns a random choice from that list. -An example of using our MOTD_ class at the Python prompt might be:: +An example of using our |MOTD| class at the Python prompt might be:: >>> from acme.motd.api import Message, MOTD >>> motd = MOTD(messages=[Message(author='Anon', text='Hello World!')]) >>> message = motd.motd() >>> print '"%s" - %s' % (message.text, message.author) "Hello World!" - Anon - >>> + >>> Well, we had to get "Hello World" in there somewhere! @@ -78,18 +78,18 @@ Create the main Application class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First of all, we need to create an object that represents the application -itself. In Envisage, this can be any object that implements the IApplication_ -interface, but is usually either an instance of the default Application_ class, +itself. In Envisage, this can be any object that implements the |IApplication| +interface, but is usually either an instance of the default |Application| class, or one derived from it. -In the MOTD_ example, we create the class in the run.py_ module as follows:: +In the |MOTD| example, we create the class in the |MOTD run| module as follows:: application = Application( id = 'acme.motd', plugins = [CorePlugin(), MOTDPlugin(), SoftwareQuotesPlugin()] ) - application.run() + application.run() In this case, we use the simplest way to tell Envisage which plugins make up the application by passing them in explicitly. Envisage applications allow you @@ -102,13 +102,13 @@ The 'acme.motd' plugin ~~~~~~~~~~~~~~~~~~~~~~ As shown above, the corresponding plugin implementation is in the -MOTDPlugin_ class:: +|MOTDPlugin| class:: class MOTDPlugin(Plugin): """ The 'Message of the Day' plugin. This plugin simply prints the 'Message of the Day' to stdout. - + """ # The IDs of the extension points that this plugin offers. @@ -182,7 +182,7 @@ MOTDPlugin_ class:: # Note that we always offer the service via its name, but look it up # via the actual protocol. from acme.motd.api import IMOTD - + # Lookup the MOTD service. motd = self.application.get_service(IMOTD) @@ -195,7 +195,7 @@ MOTDPlugin_ class:: return Although it is obviously a bit of overkill, the example shows how we would -take a MOTD_ object and register it a service for other parts of the +take a |MOTD| object and register it a service for other parts of the application to use. Sadly, in this example, there are no other parts of the application, so we just lookup and use the service ourselves! @@ -203,14 +203,14 @@ The 'acme.motd.software_quotes' plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First of all, we have to create the messages that we want to add. Remember that -when the acme.motd_ plugin advertised the extension point, it told us that -every contribution had to implement the IMessage_ interface. Happily, there is -a class that does just that already defined for us (Message_) and so we create -a simple module ('messages.py'_) and add our Message_ instances to it:: +when the |acme.motd| plugin advertised the extension point, it told us that +every contribution had to implement the |IMessage| interface. Happily, there is +a class that does just that already defined for us (|Message|) and so we create +a simple module ('messages.py'_) and add our |Message| instances to it:: messages = [ ... - + Message( author = "Martin Fowler", text = "Any fool can write code that a computer can understand. Good" @@ -226,7 +226,7 @@ a simple module ('messages.py'_) and add our Message_ instances to it:: ... ] -Now we create a plugin for the acme.motd.software_quotes_ package and tell +Now we create a plugin for the |acme.motd.software_quotes| package and tell Envisage about the messages that we have just created:: class SoftwareQuotesPlugin(Plugin): @@ -244,7 +244,7 @@ Envisage about the messages that we have just created:: # Messages for the 'Message Of The Day'. messages = List(contributes_to='acme.motd.messages') - + ########################################################################### # 'SoftwareQuotesPlugin' interface. ########################################################################### @@ -256,28 +256,3 @@ Envisage about the messages that we have just created:: from messages import messages return messages - -.. _`Python Eggs`: http://peak.telecommunity.com/DevCenter/PythonEggs - -.. _acme.motd: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/api.py - -.. _acme.motd.software_quotes: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/software_quotes/setup.py - -.. _Application: https://github.com/enthought/envisage/tree/master/envisage/application.py - -.. _`examples/MOTD`: https://github.com/enthought/envisage/tree/master/examples/MOTD - -.. _IApplication: https://github.com/enthought/envisage/tree/master/envisage/i_application.py - -.. _IMessage: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/i_message.py - -.. _Message: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/message.py - -.. _MOTD: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/motd.py - -.. _IMOTD: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/i_motd.py - -.. _MOTDPlugin: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/motd_plugin.py - -.. _run.py: https://github.com/enthought/envisage/tree/master/examples/MOTD/run.py - diff --git a/docs/source/envisage_core_documentation/message_of_the_day_(using_eggs).rst b/docs/source/envisage_core_documentation/message_of_the_day_(using_eggs).rst index ab9bce174..a56714c5c 100644 --- a/docs/source/envisage_core_documentation/message_of_the_day_(using_eggs).rst +++ b/docs/source/envisage_core_documentation/message_of_the_day_(using_eggs).rst @@ -9,8 +9,9 @@ the rare applications that is so simple that why would you bother), but it does serve to illustrate all of the fundamental aspects of building an Envisage application. -All of the code for this example can be found in the `examples/MOTD`_ directory -of the Envisage distribution. This directory contains two subdirectories: +All of the code for this example can be found in the |Message of the Day| +directory of the Envisage distribution. This directory contains two +subdirectories: dist This directory contains the actual runnable application as it *might* @@ -21,9 +22,9 @@ dist cd dist python run.py - + (or equivalent, depending on your operating system and shell) - + src This directory contains the source code for the eggs that make up the application. This is there to allow easy access to the example code, but @@ -41,38 +42,38 @@ Plain Ol' MOTD -------------- So lets take a look at our non-Envisage aware MOTD application, the code for -which is in the acme.motd_ package. A good place to start as a developer +which is in the |acme.motd| package. A good place to start as a developer *using* any package in Envisage (and, for that matter, the entire Enthought tool-suite) is to look at any interfaces and classes exposed via its 'api.py' module. In this case, there are 2 interfaces -1) IMOTD_ +1) |IMOTD| The interface for simple "Message of the Day" functionality. -2) IMessage_ +2) |IMessage| The interface supported by each message returned by the motd() method on - the IMOTD_ interface. + the |IMOTD| interface. We also (*not* coincidentally!) have 2 corresponding implementation classes: -1) MOTD_ -2) Message_ +1) |MOTD| +2) |Message| -As you can see, the MOTD_ class simply contains a list of messages and +As you can see, the |MOTD| class simply contains a list of messages and when its motd() method is called, it returns a random choice from that list. -An example of using our MOTD_ class at the Python prompt might be:: +An example of using our |MOTD| class at the Python prompt might be:: >>> from acme.motd.api import Message, MOTD >>> motd = MOTD(messages=[Message(author='Anon', text='Hello World!')]) >>> message = motd.motd() >>> print '"%s" - %s' % (message.text, message.author) "Hello World!" - Anon - >>> + >>> Well, we had to get "Hello World" in there somewhere! @@ -90,11 +91,11 @@ Create the main Application class ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First of all, we need to create an object that represents the application -itself. In Envisage, this can be any object that implements the IApplication_ -interface, but is usually either an instance of the default Application_ class, +itself. In Envisage, this can be any object that implements the |IApplication| +interface, but is usually either an instance of the default |Application| class, or one derived from it. -In the MOTD_ example, we create the class in the run.py_ module as follows:: +In the |MOTD| example, we create the class in the |MOTD run| module as follows:: def run(): """ The function that starts your application. """ @@ -104,7 +105,7 @@ In the MOTD_ example, we create the class in the run.py_ module as follows:: return Application(id='acme.motd').run() -Note that the run.py_ file also contains some boilerplate code to add the +Note that the |MOTD run| file also contains some boilerplate code to add the application's `Python Eggs`_ to the ``sys.path``, but this is not specific to Envisage - that code would be required for any egg-based application. @@ -114,7 +115,7 @@ Create the 'acme.motd' plugin This is the plugin that will deliver the "Message of the Day" functionality into the application. It will do this by declaring an extension point to allow other plugins to contribute messages, and by using contributions to -create an instance of the MOTD_ class and to publish it as a service. +create an instance of the |MOTD| class and to publish it as a service. By default, Envisage finds plugins via Python eggs, so all we have to do is to declare the existence of our plugin using the "envisage.plugins" @@ -131,7 +132,7 @@ entry point in our 'setup.py' module:: acme.motd = acme.motd.motd_plugin:MOTDPlugin ... - + """ ) @@ -145,13 +146,13 @@ Notice that we don't import the plugin from an 'api.py' module. This is to delay importing implementation code until it is actually needed. As showm above, the corresponding plugin implementation is in the -MOTDPlugin_ class:: +|MOTDPlugin| class:: class MOTDPlugin(Plugin): """ The 'Message of the Day' plugin. This plugin simply prints the 'Message of the Day' to stdout. - + """ # The IDs of the extension points that this plugin offers. @@ -225,7 +226,7 @@ MOTDPlugin_ class:: # Note that we always offer the service via its name, but look it up # via the actual protocol. from acme.motd.api import IMOTD - + # Lookup the MOTD service. motd = self.application.get_service(IMOTD) @@ -238,7 +239,7 @@ MOTDPlugin_ class:: return Although it is obviously a bit of overkill, the example shows how we would -take a MOTD_ object and register it a service for other parts of the +take a |MOTD| object and register it a service for other parts of the application to use. Sadly, in this example, there are no other parts of the application, so we just lookup and use the service ourselves! @@ -260,14 +261,14 @@ Create the 'acme.motd.software_quotes' plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ First of all, we have to create the messages that we want to add. Remember that -when the acme.motd_ plugin advertised the extension point, it told us that -every contribution had to implement the IMessage_ interface. Happily, there is -a class that does just that already defined for us (Message_) and so we create -a simple module ('messages.py'_) and add our Message_ instances to it:: +when the |acme.motd| plugin advertised the extension point, it told us that +every contribution had to implement the |IMessage| interface. Happily, there is +a class that does just that already defined for us (|Message|) and so we create +a simple module ('messages.py'_) and add our |Message| instances to it:: messages = [ ... - + Message( author = "Martin Fowler", text = "Any fool can write code that a computer can understand. Good" @@ -283,7 +284,7 @@ a simple module ('messages.py'_) and add our Message_ instances to it:: ... ] -Now we create a plugin for the acme.motd.software_quotes_ package and tell +Now we create a plugin for the |acme.motd.software_quotes| package and tell Envisage about the messages that we have just created:: class SoftwareQuotesPlugin(Plugin): @@ -301,7 +302,7 @@ Envisage about the messages that we have just created:: # Messages for the 'Message Of The Day'. messages = List(contributes_to='acme.motd.messages') - + ########################################################################### # 'SoftwareQuotesPlugin' interface. ########################################################################### @@ -314,7 +315,7 @@ Envisage about the messages that we have just created:: return messages -And finally we go to the 'setup.py' file for the acme.motd.software_quotes_ egg +And finally we go to the 'setup.py' file for the |acme.motd.software_quotes| egg and tell Envisage about the plugin:: setup( @@ -340,32 +341,9 @@ If we run the application now , we will (if all is well!) get a random, pithy quote about software development! To add more messages to the application in future, all we have to do is to -create other plugins similar to the 'acme.motd.software_quotes' egg and drop +create other plugins similar to the 'acme.motd.software_quotes' egg and drop them into the '.../examples/MOTD/dist/eggs' directory. We have successfully built our first extensible, pluggable application! .. _`Python Eggs`: http://peak.telecommunity.com/DevCenter/PythonEggs - -.. _acme.motd: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/api.py - -.. _acme.motd.software_quotes: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/software_quotes/setup.py - -.. _Application: https://github.com/enthought/envisage/tree/master/envisage/application.py - -.. _`examples/MOTD`: https://github.com/enthought/envisage/tree/master/examples/MOTD - -.. _IApplication: https://github.com/enthought/envisage/tree/master/envisage/i_application.py - -.. _IMessage: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/i_message.py - -.. _Message: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/message.py - -.. _MOTD: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/motd.py - -.. _IMOTD: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/i_motd.py - -.. _MOTDPlugin: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/motd_plugin.py - -.. _run.py: https://github.com/enthought/envisage/tree/master/examples/MOTD/run.py - diff --git a/docs/source/envisage_core_documentation/plugins.rst b/docs/source/envisage_core_documentation/plugins.rst index 65fc098a1..7c0c61601 100644 --- a/docs/source/envisage_core_documentation/plugins.rst +++ b/docs/source/envisage_core_documentation/plugins.rst @@ -17,8 +17,8 @@ uses an implementation based on `Python Eggs`_. Creating a Plugin ----------------- -All plugins must implement the IPlugin_ interface (an easy way to achieve this -is to subclass the base Plugin_ class), and should provide the following +All plugins must implement the |IPlugin| interface (an easy way to achieve this +is to subclass the base |Plugin| class), and should provide the following "housekeeping" information: - a globally unique identifier (e.g., "acme.motd") @@ -37,8 +37,8 @@ is to subclass the base Plugin_ class), and should provide the following A nice description of the intent and features of your plugin. -Here is a snippet from the `acme.motd`_ plugin that is part of the `Message of -the Day`_ example:: +Here is a snippet from the |acme.motd| plugin that is part of the |Message of +the Day| example:: class MOTDPlugin(Plugin): """ The 'Message of the Day' plugin. @@ -59,7 +59,7 @@ Plugin Lifecycle ---------------- Plugins have a lifecycle in the context of an application. There are currently -two key lifecycle methods on the IPlugin_ interface:: +two key lifecycle methods on the |IPlugin| interface:: def start(self): """ Start the plugin. @@ -92,13 +92,3 @@ method of each plugin in the reverse order that they were started in. .. _`Extension Points`: extension_points.html .. _`Python Eggs`: http://peak.telecommunity.com/DevCenter/PythonEggs .. _Services: services.html - -.. _acme.motd: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/setup.py - -.. _IPlugin: https://github.com/enthought/envisage/tree/master/envisage/i_plugin.py - -.. _`Message of the Day`: https://github.com/enthought/envisage/tree/master/examples/MOTD - -.. _MOTD: https://github.com/enthought/envisage/tree/master/examples/MOTD/acme/motd/motd.py - -.. _Plugin: https://github.com/enthought/envisage/tree/master/envisage/plugin.py diff --git a/docs/source/envisage_core_documentation/services.rst b/docs/source/envisage_core_documentation/services.rst index 54c041b0e..918ea908a 100644 --- a/docs/source/envisage_core_documentation/services.rst +++ b/docs/source/envisage_core_documentation/services.rst @@ -28,7 +28,7 @@ and it even allows you to publish your own entries for free (unlike the "real" one)! In an Envisage application, the service registry is accessed through the -following methods on the IApplication_ interface:: +following methods on the |IApplication| interface:: def get_service(self, protocol, query='', minimimize='', maximize=''): """ Return at most one service that matches the specified query. @@ -39,7 +39,7 @@ following methods on the IApplication_ interface:: """ Return the dictionary of properties associated with a service. """ - + def get_services(self, protocol, query='', minimimize='', maximize=''): """ Return all services that match the specified query. @@ -199,7 +199,7 @@ in which case only one of the services that matches the query is returned:: plumber = application.get_service(IPlumber, "price < 200") -This query would return *either* *fred* or *wilma*. +This query would return *either* *fred* or *wilma*. Using *minimize* and *maximize* ------------------------------- @@ -247,7 +247,7 @@ get_service_properties() method with the appropriate service identifier:: wilma = Plumber(name='wilma', location='BH6') wilma_id = application.register_service(IPlumber, wilma, {'price':125}) - + ... properties = application.get_service_properties(wilma_id) @@ -260,7 +260,7 @@ To set the properties for a service that has already been registered, use:: wilma = Plumber(name='wilma', location='BH6') wilma_id = application.register_service(IPlumber, wilma, {'price':125}) - + ... application.set_service_properties(wilma_id, {'price' : 150}) @@ -298,5 +298,3 @@ To register the factory, we just use 'application.register_service' as usual:: Now, the first time somebody tries to get any 'IPlumber' service, the factory is called and the returned plumber object replaces the factory in the registry. - -.. _IApplication: https://github.com/enthought/envisage/tree/master/envisage/i_application.py diff --git a/docs/source/envisage_core_documentation/workbench.rst b/docs/source/envisage_core_documentation/workbench.rst index 81b736001..fad04f76d 100644 --- a/docs/source/envisage_core_documentation/workbench.rst +++ b/docs/source/envisage_core_documentation/workbench.rst @@ -1,7 +1,7 @@ Workbench ========= -The workbench plugin, found in the envisage.ui.workbench_ package, +The workbench plugin, found in the :mod:`envisage.ui.workbench.api` package, provides a style of user interface that is often (but not exclusively) found in integrated development environments (IDEs). Note that this does not mean that all of your user interfaces must fit this pattern -- just that if they do, then @@ -59,5 +59,3 @@ widget to allow views, editors and perspectives to be contributed via plugins. :maxdepth: 2 preferences.rst - -.. _envisage.ui.workbench: https://github.com/enthought/envisage/tree/master/envisage/ui/workbench/api.py diff --git a/docs/source/tasks_user_manual/extensibility.rst b/docs/source/tasks_user_manual/extensibility.rst index 5e32624c3..3b5890f07 100644 --- a/docs/source/tasks_user_manual/extensibility.rst +++ b/docs/source/tasks_user_manual/extensibility.rst @@ -415,14 +415,13 @@ several other menu-related conveniences, can be found in .. [1] In this section, we shall be referencing--often with considerable simplification--the Attractors example code in the EnvisagePlugins - package, available `online - `_ + package, available :github-demo:`online ` and in the ETS distribution. .. [2] Although they are expanded into Pyface action items, schemas belong to a distinct API. It is beyond the scope of this document to describe the - Pyface action API. For lack of more complete documentation, the reader is - referred to the `source code - `_. + Pyface action API. For more complete documentation, the reader is + referred to the `Pyface documentation + `_. .. [3] Tasks differs from the Workbench in this regard. diff --git a/docs/source/tasks_user_manual/layout.rst b/docs/source/tasks_user_manual/layout.rst index 96bacacba..a2eb15739 100644 --- a/docs/source/tasks_user_manual/layout.rst +++ b/docs/source/tasks_user_manual/layout.rst @@ -43,7 +43,7 @@ Defining a Task --------------- Minimally, a task is defined by subclassing ``Task`` and providing a central -pane. For example, we define a task for editing Python scripts [3]_:: +pane. For example, we define a task for editing Python scripts:: from pyface.tasks.api import Task @@ -234,9 +234,3 @@ appears multiple times in a layout. .. [2] Throughout this document, "``Task``" will refer to the class of that name in the Tasks API, while "task" will be reserved for the general UI concept, and similarly for other terms. - -.. [3] In this and the subsequent section, we will be referencing (often in - abbreviated form) the Tasks example code in the TraitsGUI package, - available `online - `_ and - in the ETS distribution. diff --git a/docs/source/tasks_user_manual/menus.rst b/docs/source/tasks_user_manual/menus.rst index c134c6d66..f9429c877 100644 --- a/docs/source/tasks_user_manual/menus.rst +++ b/docs/source/tasks_user_manual/menus.rst @@ -24,7 +24,7 @@ Defining a Menu Bar Resuming our example of the script editing task from the previous section, we shall define some menu items for opening and saving files. As in Traits UI and -Pyface, individual menu items are instances of the ``Action`` class [1]_. We +Pyface, individual menu items are instances of the ``Action`` class. We might define the 'Open' action as follows:: from pyface.action.api import Action @@ -128,8 +128,3 @@ files to our script editing task:: TaskAction(method='save', tooltip='Save the current file', image=ImageResource('document_save'))) ] - -.. rubric:: Footnotes - -.. [1] The most convenient reference in this case is the `source code - `_ itself. diff --git a/examples/plugins/tasks/attractors/__init__.py b/envisage/examples/__init__.py similarity index 100% rename from examples/plugins/tasks/attractors/__init__.py rename to envisage/examples/__init__.py diff --git a/envisage/examples/_demo.py b/envisage/examples/_demo.py new file mode 100644 index 000000000..3259a618c --- /dev/null +++ b/envisage/examples/_demo.py @@ -0,0 +1,36 @@ +# (C) Copyright 2007-2020 Enthought, Inc., Austin, TX +# All rights reserved. +# +# This software is provided without warranty under the terms of the BSD +# license included in LICENSE.txt and may be redistributed only under +# the conditions described in the aforementioned license. The license +# is also available online at http://www.enthought.com/licenses/BSD.txt +# +# Thanks for using Enthought open source! +""" Utilities for supporting Envisage's demo examples. +""" + +import contextlib +import os +import sys + + +@contextlib.contextmanager +def demo_path(path): + """ Context manager to temporarily insert the directory containing + the demo script to sys.path such that demo examples can be run using + local packages. + + This function should only be used by Envisage example files. + + Parameters + ---------- + path : Path-like + Path to the demo script to be run. + """ + path = os.path.dirname(os.fspath(path)) + try: + sys.path.insert(0, path) + yield + finally: + sys.path.remove(path) diff --git a/envisage/examples/_etsdemo_info.py b/envisage/examples/_etsdemo_info.py new file mode 100644 index 000000000..89c888717 --- /dev/null +++ b/envisage/examples/_etsdemo_info.py @@ -0,0 +1,36 @@ +# (C) Copyright 2005-2020 Enthought, Inc., Austin, TX +# All rights reserved. +# +# This software is provided without warranty under the terms of the BSD +# license included in LICENSE.txt and may be redistributed only under +# the conditions described in the aforementioned license. The license +# is also available online at http://www.enthought.com/licenses/BSD.txt +# +# Thanks for using Enthought open source! + +""" This module provides functions to be advertised in the distribution +entry points. +""" + +import pkg_resources + + +def info(request): + """ Return a configuration for contributing examples to the + Demo application. + Parameters + ---------- + request : dict + Information provided by the demo application. + Currently this is a placeholder. + Returns + ------- + response : dict + """ + return dict( + version=1, + name="Envisage Examples", + root=( + pkg_resources.resource_filename("envisage.examples", "demo") + ), + ) diff --git a/examples/GUI_Application/traitsui_gui_app.py b/envisage/examples/demo/GUI_Application/traitsui_gui_app.py similarity index 100% rename from examples/GUI_Application/traitsui_gui_app.py rename to envisage/examples/demo/GUI_Application/traitsui_gui_app.py diff --git a/examples/Hello_World/hello_world.py b/envisage/examples/demo/Hello_World/hello_world.py similarity index 92% rename from examples/Hello_World/hello_world.py rename to envisage/examples/demo/Hello_World/hello_world.py index fc83d33a5..1e6eaa623 100644 --- a/examples/Hello_World/hello_world.py +++ b/envisage/examples/demo/Hello_World/hello_world.py @@ -1,20 +1,10 @@ """ The Envisage version of the old chestnut. """ - -# Standard library imports. -import logging - # Enthought library imports. from envisage.api import Application, ExtensionPoint, Plugin from traits.api import List, Str -# Create a log file. -logger = logging.getLogger() -logger.addHandler(logging.FileHandler("hello_world.log", "w", encoding="utf-8")) -logger.setLevel(logging.DEBUG) - - class HelloWorld(Plugin): """ The 'Hello World' plugin. diff --git a/examples/MOTD/acme/__init__.py b/envisage/examples/demo/MOTD/acme/__init__.py similarity index 100% rename from examples/MOTD/acme/__init__.py rename to envisage/examples/demo/MOTD/acme/__init__.py diff --git a/examples/MOTD/acme/motd/__init__.py b/envisage/examples/demo/MOTD/acme/motd/__init__.py similarity index 100% rename from examples/MOTD/acme/motd/__init__.py rename to envisage/examples/demo/MOTD/acme/motd/__init__.py diff --git a/examples/MOTD/acme/motd/api.py b/envisage/examples/demo/MOTD/acme/motd/api.py similarity index 100% rename from examples/MOTD/acme/motd/api.py rename to envisage/examples/demo/MOTD/acme/motd/api.py diff --git a/examples/MOTD/acme/motd/i_message.py b/envisage/examples/demo/MOTD/acme/motd/i_message.py similarity index 100% rename from examples/MOTD/acme/motd/i_message.py rename to envisage/examples/demo/MOTD/acme/motd/i_message.py diff --git a/examples/MOTD/acme/motd/i_motd.py b/envisage/examples/demo/MOTD/acme/motd/i_motd.py similarity index 100% rename from examples/MOTD/acme/motd/i_motd.py rename to envisage/examples/demo/MOTD/acme/motd/i_motd.py diff --git a/examples/MOTD/acme/motd/message.py b/envisage/examples/demo/MOTD/acme/motd/message.py similarity index 100% rename from examples/MOTD/acme/motd/message.py rename to envisage/examples/demo/MOTD/acme/motd/message.py diff --git a/examples/MOTD/acme/motd/motd.py b/envisage/examples/demo/MOTD/acme/motd/motd.py similarity index 100% rename from examples/MOTD/acme/motd/motd.py rename to envisage/examples/demo/MOTD/acme/motd/motd.py diff --git a/examples/MOTD/acme/motd/motd_plugin.py b/envisage/examples/demo/MOTD/acme/motd/motd_plugin.py similarity index 100% rename from examples/MOTD/acme/motd/motd_plugin.py rename to envisage/examples/demo/MOTD/acme/motd/motd_plugin.py diff --git a/examples/MOTD/acme/motd/software_quotes/__init__.py b/envisage/examples/demo/MOTD/acme/motd/software_quotes/__init__.py similarity index 100% rename from examples/MOTD/acme/motd/software_quotes/__init__.py rename to envisage/examples/demo/MOTD/acme/motd/software_quotes/__init__.py diff --git a/examples/MOTD/acme/motd/software_quotes/messages.py b/envisage/examples/demo/MOTD/acme/motd/software_quotes/messages.py similarity index 100% rename from examples/MOTD/acme/motd/software_quotes/messages.py rename to envisage/examples/demo/MOTD/acme/motd/software_quotes/messages.py diff --git a/examples/MOTD/acme/motd/software_quotes/software_quotes_plugin.py b/envisage/examples/demo/MOTD/acme/motd/software_quotes/software_quotes_plugin.py similarity index 100% rename from examples/MOTD/acme/motd/software_quotes/software_quotes_plugin.py rename to envisage/examples/demo/MOTD/acme/motd/software_quotes/software_quotes_plugin.py diff --git a/envisage/examples/demo/MOTD/run.py b/envisage/examples/demo/MOTD/run.py new file mode 100644 index 000000000..4e412ae7d --- /dev/null +++ b/envisage/examples/demo/MOTD/run.py @@ -0,0 +1,31 @@ +""" Run the MOTD example application. """ + +# Enthought library imports. +from envisage.api import Application, CorePlugin + + +def main(): + """ Run the application. """ + # Import here so that this script can be run from anywhere without + # having to install the packages. + from acme.motd.motd_plugin import MOTDPlugin + from acme.motd.software_quotes.software_quotes_plugin import ( + SoftwareQuotesPlugin, + ) + # Create an application containing the appropriate plugins. + application = Application( + id="acme.motd", + plugins=[CorePlugin(), MOTDPlugin(), SoftwareQuotesPlugin()], + ) + + # Run it! + return application.run() + + +if __name__ == "__main__": + # This context manager is added so that one can run this example from any + # directory without necessarily having installed the examples as packages. + from envisage.examples._demo import demo_path + + with demo_path(__file__): + main() diff --git a/examples/plugins/tasks/attractors/model/__init__.py b/envisage/examples/demo/plugins/tasks/attractors/__init__.py similarity index 100% rename from examples/plugins/tasks/attractors/model/__init__.py rename to envisage/examples/demo/plugins/tasks/attractors/__init__.py diff --git a/examples/plugins/tasks/attractors/attractors_application.py b/envisage/examples/demo/plugins/tasks/attractors/attractors_application.py similarity index 100% rename from examples/plugins/tasks/attractors/attractors_application.py rename to envisage/examples/demo/plugins/tasks/attractors/attractors_application.py diff --git a/examples/plugins/tasks/attractors/attractors_plugin.py b/envisage/examples/demo/plugins/tasks/attractors/attractors_plugin.py similarity index 100% rename from examples/plugins/tasks/attractors/attractors_plugin.py rename to envisage/examples/demo/plugins/tasks/attractors/attractors_plugin.py diff --git a/examples/plugins/tasks/attractors/attractors_preferences.py b/envisage/examples/demo/plugins/tasks/attractors/attractors_preferences.py similarity index 100% rename from examples/plugins/tasks/attractors/attractors_preferences.py rename to envisage/examples/demo/plugins/tasks/attractors/attractors_preferences.py diff --git a/examples/plugins/tasks/attractors/help/henon.html b/envisage/examples/demo/plugins/tasks/attractors/help/henon.html similarity index 100% rename from examples/plugins/tasks/attractors/help/henon.html rename to envisage/examples/demo/plugins/tasks/attractors/help/henon.html diff --git a/examples/plugins/tasks/attractors/help/images/henon1.png b/envisage/examples/demo/plugins/tasks/attractors/help/images/henon1.png similarity index 100% rename from examples/plugins/tasks/attractors/help/images/henon1.png rename to envisage/examples/demo/plugins/tasks/attractors/help/images/henon1.png diff --git a/examples/plugins/tasks/attractors/help/images/lorenz1.png b/envisage/examples/demo/plugins/tasks/attractors/help/images/lorenz1.png similarity index 100% rename from examples/plugins/tasks/attractors/help/images/lorenz1.png rename to envisage/examples/demo/plugins/tasks/attractors/help/images/lorenz1.png diff --git a/examples/plugins/tasks/attractors/help/images/lorenz2.png b/envisage/examples/demo/plugins/tasks/attractors/help/images/lorenz2.png similarity index 100% rename from examples/plugins/tasks/attractors/help/images/lorenz2.png rename to envisage/examples/demo/plugins/tasks/attractors/help/images/lorenz2.png diff --git a/examples/plugins/tasks/attractors/help/images/lorenz3.png b/envisage/examples/demo/plugins/tasks/attractors/help/images/lorenz3.png similarity index 100% rename from examples/plugins/tasks/attractors/help/images/lorenz3.png rename to envisage/examples/demo/plugins/tasks/attractors/help/images/lorenz3.png diff --git a/examples/plugins/tasks/attractors/help/images/rossler1.png b/envisage/examples/demo/plugins/tasks/attractors/help/images/rossler1.png similarity index 100% rename from examples/plugins/tasks/attractors/help/images/rossler1.png rename to envisage/examples/demo/plugins/tasks/attractors/help/images/rossler1.png diff --git a/examples/plugins/tasks/attractors/help/images/rossler2.png b/envisage/examples/demo/plugins/tasks/attractors/help/images/rossler2.png similarity index 100% rename from examples/plugins/tasks/attractors/help/images/rossler2.png rename to envisage/examples/demo/plugins/tasks/attractors/help/images/rossler2.png diff --git a/examples/plugins/tasks/attractors/help/images/rossler3.png b/envisage/examples/demo/plugins/tasks/attractors/help/images/rossler3.png similarity index 100% rename from examples/plugins/tasks/attractors/help/images/rossler3.png rename to envisage/examples/demo/plugins/tasks/attractors/help/images/rossler3.png diff --git a/examples/plugins/tasks/attractors/help/lorenz.html b/envisage/examples/demo/plugins/tasks/attractors/help/lorenz.html similarity index 100% rename from examples/plugins/tasks/attractors/help/lorenz.html rename to envisage/examples/demo/plugins/tasks/attractors/help/lorenz.html diff --git a/examples/plugins/tasks/attractors/help/rossler.html b/envisage/examples/demo/plugins/tasks/attractors/help/rossler.html similarity index 100% rename from examples/plugins/tasks/attractors/help/rossler.html rename to envisage/examples/demo/plugins/tasks/attractors/help/rossler.html diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/action/__init__.py b/envisage/examples/demo/plugins/tasks/attractors/model/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/action/__init__.py rename to envisage/examples/demo/plugins/tasks/attractors/model/__init__.py diff --git a/examples/plugins/tasks/attractors/model/henon.py b/envisage/examples/demo/plugins/tasks/attractors/model/henon.py similarity index 100% rename from examples/plugins/tasks/attractors/model/henon.py rename to envisage/examples/demo/plugins/tasks/attractors/model/henon.py diff --git a/examples/plugins/tasks/attractors/model/i_model_2d.py b/envisage/examples/demo/plugins/tasks/attractors/model/i_model_2d.py similarity index 100% rename from examples/plugins/tasks/attractors/model/i_model_2d.py rename to envisage/examples/demo/plugins/tasks/attractors/model/i_model_2d.py diff --git a/examples/plugins/tasks/attractors/model/i_model_3d.py b/envisage/examples/demo/plugins/tasks/attractors/model/i_model_3d.py similarity index 100% rename from examples/plugins/tasks/attractors/model/i_model_3d.py rename to envisage/examples/demo/plugins/tasks/attractors/model/i_model_3d.py diff --git a/examples/plugins/tasks/attractors/model/i_plottable_2d.py b/envisage/examples/demo/plugins/tasks/attractors/model/i_plottable_2d.py similarity index 100% rename from examples/plugins/tasks/attractors/model/i_plottable_2d.py rename to envisage/examples/demo/plugins/tasks/attractors/model/i_plottable_2d.py diff --git a/examples/plugins/tasks/attractors/model/lorenz.py b/envisage/examples/demo/plugins/tasks/attractors/model/lorenz.py similarity index 100% rename from examples/plugins/tasks/attractors/model/lorenz.py rename to envisage/examples/demo/plugins/tasks/attractors/model/lorenz.py diff --git a/examples/plugins/tasks/attractors/model/rossler.py b/envisage/examples/demo/plugins/tasks/attractors/model/rossler.py similarity index 100% rename from examples/plugins/tasks/attractors/model/rossler.py rename to envisage/examples/demo/plugins/tasks/attractors/model/rossler.py diff --git a/examples/plugins/tasks/attractors/model_config_pane.py b/envisage/examples/demo/plugins/tasks/attractors/model_config_pane.py similarity index 100% rename from examples/plugins/tasks/attractors/model_config_pane.py rename to envisage/examples/demo/plugins/tasks/attractors/model_config_pane.py diff --git a/examples/plugins/tasks/attractors/model_help_pane.py b/envisage/examples/demo/plugins/tasks/attractors/model_help_pane.py similarity index 100% rename from examples/plugins/tasks/attractors/model_help_pane.py rename to envisage/examples/demo/plugins/tasks/attractors/model_help_pane.py diff --git a/examples/plugins/tasks/attractors/plot_2d_pane.py b/envisage/examples/demo/plugins/tasks/attractors/plot_2d_pane.py similarity index 100% rename from examples/plugins/tasks/attractors/plot_2d_pane.py rename to envisage/examples/demo/plugins/tasks/attractors/plot_2d_pane.py diff --git a/examples/plugins/tasks/attractors/plot_3d_pane.py b/envisage/examples/demo/plugins/tasks/attractors/plot_3d_pane.py similarity index 100% rename from examples/plugins/tasks/attractors/plot_3d_pane.py rename to envisage/examples/demo/plugins/tasks/attractors/plot_3d_pane.py diff --git a/examples/plugins/tasks/attractors/preferences.ini b/envisage/examples/demo/plugins/tasks/attractors/preferences.ini similarity index 100% rename from examples/plugins/tasks/attractors/preferences.ini rename to envisage/examples/demo/plugins/tasks/attractors/preferences.ini diff --git a/examples/plugins/tasks/attractors/visualize_2d_task.py b/envisage/examples/demo/plugins/tasks/attractors/visualize_2d_task.py similarity index 100% rename from examples/plugins/tasks/attractors/visualize_2d_task.py rename to envisage/examples/demo/plugins/tasks/attractors/visualize_2d_task.py diff --git a/examples/plugins/tasks/attractors/visualize_3d_task.py b/envisage/examples/demo/plugins/tasks/attractors/visualize_3d_task.py similarity index 100% rename from examples/plugins/tasks/attractors/visualize_3d_task.py rename to envisage/examples/demo/plugins/tasks/attractors/visualize_3d_task.py diff --git a/examples/plugins/tasks/index.rst b/envisage/examples/demo/plugins/tasks/index.rst similarity index 78% rename from examples/plugins/tasks/index.rst rename to envisage/examples/demo/plugins/tasks/index.rst index 1929a7178..d1b1949f1 100644 --- a/examples/plugins/tasks/index.rst +++ b/envisage/examples/demo/plugins/tasks/index.rst @@ -2,9 +2,7 @@ Welcome to the attractors example. To run the application:: - python -m attractors.run - -from this directory. + python run_attractor.py Note that this example application depends on the following additional packages:: diff --git a/envisage/examples/demo/plugins/tasks/run_attractor.py b/envisage/examples/demo/plugins/tasks/run_attractor.py new file mode 100644 index 000000000..ff59205de --- /dev/null +++ b/envisage/examples/demo/plugins/tasks/run_attractor.py @@ -0,0 +1,26 @@ +# Plugin imports. +from envisage.api import CorePlugin +from envisage.ui.tasks.api import TasksPlugin + + +def main(argv): + """ Run the application. + """ + # Import here so that this script can be run from anywhere without + # having to install the packages. + from attractors.attractors_plugin import AttractorsPlugin + from attractors.attractors_application import AttractorsApplication + + plugins = [CorePlugin(), TasksPlugin(), AttractorsPlugin()] + app = AttractorsApplication(plugins=plugins) + app.run() + + +if __name__ == "__main__": + import sys + # This context manager is added so that one can run this example from any + # directory without necessarily having installed the examples as packages. + from envisage.examples._demo import demo_path + + with demo_path(__file__): + main(sys.argv) diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/perspective/__init__.py b/envisage/examples/tests/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/perspective/__init__.py rename to envisage/examples/tests/__init__.py diff --git a/envisage/examples/tests/test__demo.py b/envisage/examples/tests/test__demo.py new file mode 100644 index 000000000..64319d5b6 --- /dev/null +++ b/envisage/examples/tests/test__demo.py @@ -0,0 +1,24 @@ +# (C) Copyright 2007-2020 Enthought, Inc., Austin, TX +# All rights reserved. +# +# This software is provided without warranty under the terms of the BSD +# license included in LICENSE.txt and may be redistributed only under +# the conditions described in the aforementioned license. The license +# is also available online at http://www.enthought.com/licenses/BSD.txt +# +# Thanks for using Enthought open source! +import os +import sys +import unittest + +from envisage.examples._demo import demo_path + + +class TestDemoUtilities(unittest.TestCase): + """ Test utility functions in the _demo module.""" + + def test_sys_path_inserted(self): + path = os.path.join("dirname", "file.py") + with demo_path(path): + self.assertIn("dirname", sys.path) + self.assertNotIn("dirname", sys.path) diff --git a/envisage/examples/tests/test_etsdemo_info.py b/envisage/examples/tests/test_etsdemo_info.py new file mode 100644 index 000000000..7b0f221af --- /dev/null +++ b/envisage/examples/tests/test_etsdemo_info.py @@ -0,0 +1,22 @@ +# (C) Copyright 2007-2020 Enthought, Inc., Austin, TX +# All rights reserved. +# +# This software is provided without warranty under the terms of the BSD +# license included in LICENSE.txt and may be redistributed only under +# the conditions described in the aforementioned license. The license +# is also available online at http://www.enthought.com/licenses/BSD.txt +# +# Thanks for using Enthought open source! +import os +import pkg_resources +import unittest + +from envisage.examples._etsdemo_info import info + + +class TestETSDemoInfo(unittest.TestCase): + + def test_info(self): + # input to info is currently just a placeholder + response = info({}) + self.assertTrue(os.path.exists(response['root'])) diff --git a/envisage/plugin.py b/envisage/plugin.py index f58647299..0a70c35ec 100644 --- a/envisage/plugin.py +++ b/envisage/plugin.py @@ -327,7 +327,7 @@ def _anytrait_changed(self, trait_name, old, new): else: added = new removed = old - index = slice(0, max(len(old), len(new))) + index = slice(0, len(old)) # Let the extension registry know about the change. self._fire_extension_point_changed( diff --git a/envisage/tests/test_extension_point_changed.py b/envisage/tests/test_extension_point_changed.py index 38025682b..2faf146d3 100644 --- a/envisage/tests/test_extension_point_changed.py +++ b/envisage/tests/test_extension_point_changed.py @@ -236,6 +236,9 @@ def test_assign_non_empty_list(self): # won't fire a changed event. self.assertEqual([1, 2, 3, 98, 99, 100], a.x) + # Keep the old values for later slicing check + source_values = list(a.x) + # Assign a non-empty list to one of the plugin's contributions. b.x = [2, 4, 6, 8] @@ -259,8 +262,19 @@ def test_assign_non_empty_list(self): self.assertEqual("x_items", listener.trait_name) self.assertEqual([2, 4, 6, 8], listener.new.added) self.assertEqual([1, 2, 3], listener.new.removed) + + # The removed entry should match what the old values say + self.assertEqual( + listener.new.removed, source_values[listener.new.index] + ) + + # If we use the index and apply the changes to the old list, we should + # recover the new list + source_values[listener.new.index] = listener.new.added + self.assertEqual(source_values, application.get_extensions("a.x")) + self.assertEqual(0, listener.new.index.start) - self.assertEqual(4, listener.new.index.stop) + self.assertEqual(3, listener.new.index.stop) def test_add_plugin(self): """ add plugin """ diff --git a/examples/Hello_World/.gitignore b/examples/Hello_World/.gitignore deleted file mode 100644 index 23c09bd8f..000000000 --- a/examples/Hello_World/.gitignore +++ /dev/null @@ -1 +0,0 @@ -hello_world.log diff --git a/examples/MOTD/README.txt b/examples/MOTD/README.txt deleted file mode 100644 index a34253a3e..000000000 --- a/examples/MOTD/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -Welcome to the "Message of the Day" (MOTD) example. - -To run the application:: - - ``python run.py`` - - or equivalent, depending on your operating system and shell. - diff --git a/examples/MOTD/run.py b/examples/MOTD/run.py deleted file mode 100644 index 0c78b6762..000000000 --- a/examples/MOTD/run.py +++ /dev/null @@ -1,37 +0,0 @@ -""" Run the MOTD example application. """ - - -# Standard library imports. -import logging - -# Enthought library imports. -from envisage.api import Application, CorePlugin - -# Example plugins. -from acme.motd.motd_plugin import MOTDPlugin -from acme.motd.software_quotes.software_quotes_plugin import ( - SoftwareQuotesPlugin, -) - - -# Do whatever you want to do with log messages! Here we create a log file. -logger = logging.getLogger() -logger.addHandler(logging.FileHandler("acme_motd.log", "w", encoding="utf-8")) -logger.setLevel(logging.DEBUG) - - -def main(): - """ Run the application. """ - - # Create an application containing the appropriate plugins. - application = Application( - id="acme.motd", - plugins=[CorePlugin(), MOTDPlugin(), SoftwareQuotesPlugin()], - ) - - # Run it! - return application.run() - - -if __name__ == "__main__": - main() diff --git a/examples/README.rst b/examples/README.rst new file mode 100644 index 000000000..584f5aa8d --- /dev/null +++ b/examples/README.rst @@ -0,0 +1,3 @@ +Examples have been moved to sit in envisage/examples/demo. The examples +remaining here in the legacy directory have known problems. See +enthought/envisage#329, enthought/envisage#330, enthought/envisage#381 \ No newline at end of file diff --git a/examples/MOTD_Using_Eggs/README.txt b/examples/legacy/MOTD_Using_Eggs/README.txt similarity index 100% rename from examples/MOTD_Using_Eggs/README.txt rename to examples/legacy/MOTD_Using_Eggs/README.txt diff --git a/examples/MOTD_Using_Eggs/dist/run.py b/examples/legacy/MOTD_Using_Eggs/dist/run.py similarity index 100% rename from examples/MOTD_Using_Eggs/dist/run.py rename to examples/legacy/MOTD_Using_Eggs/dist/run.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/__init__.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/__init__.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/__init__.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/__init__.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/__init__.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/__init__.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/__init__.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/__init__.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/__init__.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/__init__.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/__init__.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/__init__.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/messages.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/messages.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/messages.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/messages.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/software_quotes_plugin.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/software_quotes_plugin.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/software_quotes_plugin.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/acme/motd/software_quotes/software_quotes_plugin.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/setup.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/setup.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd.software_quotes/setup.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd.software_quotes/setup.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/acme/__init__.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/__init__.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/acme/__init__.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/__init__.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/__init__.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/__init__.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/__init__.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/__init__.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/api.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/api.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/api.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/api.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/i_message.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/i_message.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/i_message.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/i_message.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/i_motd.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/i_motd.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/i_motd.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/i_motd.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/message.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/message.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/message.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/message.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/motd.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/motd.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/motd.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/motd.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/motd_plugin.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/motd_plugin.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/acme/motd/motd_plugin.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/acme/motd/motd_plugin.py diff --git a/examples/MOTD_Using_Eggs/src/acme.motd/setup.py b/examples/legacy/MOTD_Using_Eggs/src/acme.motd/setup.py similarity index 100% rename from examples/MOTD_Using_Eggs/src/acme.motd/setup.py rename to examples/legacy/MOTD_Using_Eggs/src/acme.motd/setup.py diff --git a/examples/plugins/tasks/ipython_kernel/example.py b/examples/legacy/plugins/tasks/ipython_kernel/example.py similarity index 92% rename from examples/plugins/tasks/ipython_kernel/example.py rename to examples/legacy/plugins/tasks/ipython_kernel/example.py index 623ff05b5..94e44d613 100644 --- a/examples/plugins/tasks/ipython_kernel/example.py +++ b/examples/legacy/plugins/tasks/ipython_kernel/example.py @@ -1,6 +1,3 @@ -# Standard library imports. -import logging - # Enthought library imports. from envisage.api import CorePlugin, Plugin from envisage.plugins.ipython_kernel.api import ( @@ -18,9 +15,6 @@ from example_task import ExampleTask -logger = logging.getLogger(__name__) - - class ExamplePlugin(Plugin): #### 'IPlugin' interface ############################################## @@ -103,14 +97,8 @@ def run(self): return started - def _application_initialized_fired(self): - logger.info("APPLICATION INITIALIZED") - if __name__ == "__main__": - import logging - - logging.basicConfig(level=logging.DEBUG) app = ExampleApplication( plugins=[ diff --git a/examples/plugins/tasks/ipython_kernel/example_panes.py b/examples/legacy/plugins/tasks/ipython_kernel/example_panes.py similarity index 100% rename from examples/plugins/tasks/ipython_kernel/example_panes.py rename to examples/legacy/plugins/tasks/ipython_kernel/example_panes.py diff --git a/examples/plugins/tasks/ipython_kernel/example_task.py b/examples/legacy/plugins/tasks/ipython_kernel/example_task.py similarity index 100% rename from examples/plugins/tasks/ipython_kernel/example_task.py rename to examples/legacy/plugins/tasks/ipython_kernel/example_task.py diff --git a/examples/plugins/tasks/ipython_kernel/i_python_editor.py b/examples/legacy/plugins/tasks/ipython_kernel/i_python_editor.py similarity index 100% rename from examples/plugins/tasks/ipython_kernel/i_python_editor.py rename to examples/legacy/plugins/tasks/ipython_kernel/i_python_editor.py diff --git a/examples/plugins/tasks/ipython_kernel/images/document_new.png b/examples/legacy/plugins/tasks/ipython_kernel/images/document_new.png similarity index 100% rename from examples/plugins/tasks/ipython_kernel/images/document_new.png rename to examples/legacy/plugins/tasks/ipython_kernel/images/document_new.png diff --git a/examples/plugins/tasks/ipython_kernel/images/document_open.png b/examples/legacy/plugins/tasks/ipython_kernel/images/document_open.png similarity index 100% rename from examples/plugins/tasks/ipython_kernel/images/document_open.png rename to examples/legacy/plugins/tasks/ipython_kernel/images/document_open.png diff --git a/examples/plugins/tasks/ipython_kernel/images/document_save.png b/examples/legacy/plugins/tasks/ipython_kernel/images/document_save.png similarity index 100% rename from examples/plugins/tasks/ipython_kernel/images/document_save.png rename to examples/legacy/plugins/tasks/ipython_kernel/images/document_save.png diff --git a/examples/plugins/tasks/ipython_kernel/images/image_LICENSE.txt b/examples/legacy/plugins/tasks/ipython_kernel/images/image_LICENSE.txt similarity index 100% rename from examples/plugins/tasks/ipython_kernel/images/image_LICENSE.txt rename to examples/legacy/plugins/tasks/ipython_kernel/images/image_LICENSE.txt diff --git a/examples/plugins/tasks/ipython_kernel/python_editor.py b/examples/legacy/plugins/tasks/ipython_kernel/python_editor.py similarity index 100% rename from examples/plugins/tasks/ipython_kernel/python_editor.py rename to examples/legacy/plugins/tasks/ipython_kernel/python_editor.py diff --git a/examples/plugins/workbench/AcmeLab/acme/__init__.py b/examples/legacy/plugins/workbench/AcmeLab/acme/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/__init__.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/__init__.py diff --git a/examples/plugins/workbench/AcmeLab/acme/acmelab/__init__.py b/examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/acmelab/__init__.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/__init__.py diff --git a/examples/plugins/workbench/AcmeLab/acme/acmelab/acmelab.py b/examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/acmelab.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/acmelab/acmelab.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/acmelab.py diff --git a/examples/plugins/workbench/AcmeLab/acme/acmelab/api.py b/examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/api.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/acmelab/api.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/api.py diff --git a/examples/plugins/workbench/AcmeLab/acme/acmelab/images/about.png b/examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/images/about.png similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/acmelab/images/about.png rename to examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/images/about.png diff --git a/examples/plugins/workbench/AcmeLab/acme/acmelab/images/acmelab.ico b/examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/images/acmelab.ico similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/acmelab/images/acmelab.ico rename to examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/images/acmelab.ico diff --git a/examples/plugins/workbench/AcmeLab/acme/acmelab/images/image_LICENSE.txt b/examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/images/image_LICENSE.txt similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/acmelab/images/image_LICENSE.txt rename to examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/images/image_LICENSE.txt diff --git a/examples/plugins/workbench/AcmeLab/acme/acmelab/images/splash.jpg b/examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/images/splash.jpg similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/acmelab/images/splash.jpg rename to examples/legacy/plugins/workbench/AcmeLab/acme/acmelab/images/splash.jpg diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/__init__.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/__init__.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/__init__.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/acme_preferences_page.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/acme_preferences_page.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/acme_preferences_page.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/acme_preferences_page.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/acme_workbench_plugin.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/acme_workbench_plugin.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/acme_workbench_plugin.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/acme_workbench_plugin.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/view/__init__.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/action/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/view/__init__.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/action/__init__.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/action/new_view.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/action/new_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/action/new_view.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/action/new_view.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/action/new_view_action.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/action/new_view_action.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/action/new_view_action.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/action/new_view_action.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/__init__.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/perspective/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/__init__.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/perspective/__init__.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/perspective/api.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/perspective/api.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/perspective/api.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/perspective/api.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/perspective/bar_perspective.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/perspective/bar_perspective.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/perspective/bar_perspective.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/perspective/bar_perspective.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/perspective/foo_perspective.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/perspective/foo_perspective.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/perspective/foo_perspective.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/perspective/foo_perspective.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/test_action_set.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/test_action_set.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/test_action_set.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/test_action_set.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/__init__.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/__init__.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/__init__.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/view/api.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/api.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/view/api.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/api.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/view/black_view.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/black_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/view/black_view.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/black_view.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/view/blue_view.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/blue_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/view/blue_view.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/blue_view.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/view/color_view.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/color_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/view/color_view.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/color_view.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/view/green_view.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/green_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/view/green_view.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/green_view.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/view/red_view.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/red_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/view/red_view.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/red_view.py diff --git a/examples/plugins/workbench/AcmeLab/acme/workbench/view/yellow_view.py b/examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/yellow_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/acme/workbench/view/yellow_view.py rename to examples/legacy/plugins/workbench/AcmeLab/acme/workbench/view/yellow_view.py diff --git a/examples/plugins/workbench/AcmeLab/run.py b/examples/legacy/plugins/workbench/AcmeLab/run.py similarity index 100% rename from examples/plugins/workbench/AcmeLab/run.py rename to examples/legacy/plugins/workbench/AcmeLab/run.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/README.txt b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/README.txt similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/README.txt rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/README.txt diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/dist/run.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/dist/run.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/dist/run.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/dist/run.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/__init__.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/__init__.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/__init__.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/__init__.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/__init__.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/__init__.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/acmelab.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/acmelab.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/acmelab.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/acmelab.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/api.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/api.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/api.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/api.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/about.png b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/about.png similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/about.png rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/about.png diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/acmelab.ico b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/acmelab.ico similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/acmelab.ico rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/acmelab.ico diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/image_LICENSE.txt b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/image_LICENSE.txt similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/image_LICENSE.txt rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/image_LICENSE.txt diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/splash.jpg b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/splash.jpg similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/splash.jpg rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/acme/acmelab/images/splash.jpg diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/setup.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/setup.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/setup.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.acmelab/setup.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/__init__.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/__init__.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/__init__.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/__init__.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/__init__.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/__init__.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/__init__.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/acme_preferences_page.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/acme_preferences_page.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/acme_preferences_page.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/acme_preferences_page.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/acme_workbench_plugin.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/acme_workbench_plugin.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/acme_workbench_plugin.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/acme_workbench_plugin.py diff --git a/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/__init__.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/api.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/api.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/api.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/api.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/bar_perspective.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/bar_perspective.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/bar_perspective.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/bar_perspective.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/foo_perspective.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/foo_perspective.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/foo_perspective.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/perspective/foo_perspective.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/test_action_set.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/test_action_set.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/test_action_set.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/test_action_set.py diff --git a/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/__init__.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/api.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/api.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/api.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/api.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/black_view.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/black_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/black_view.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/black_view.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/blue_view.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/blue_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/blue_view.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/blue_view.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/color_view.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/color_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/color_view.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/color_view.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/green_view.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/green_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/green_view.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/green_view.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/red_view.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/red_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/red_view.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/red_view.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/yellow_view.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/yellow_view.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/yellow_view.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/acme/workbench/view/yellow_view.py diff --git a/examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/setup.py b/examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/setup.py similarity index 100% rename from examples/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/setup.py rename to examples/legacy/plugins/workbench/AcmeLabUsingEggs/src/acme.workbench/setup.py diff --git a/examples/plugins/workbench/Lorenz/acme/__init__.py b/examples/legacy/plugins/workbench/Lorenz/acme/__init__.py similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/__init__.py rename to examples/legacy/plugins/workbench/Lorenz/acme/__init__.py diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/__init__.py b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/__init__.py similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/__init__.py rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/__init__.py diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/api.py b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/api.py similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/api.py rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/api.py diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/images/about.png b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/images/about.png similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/images/about.png rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/images/about.png diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/images/image_LICENSE.txt b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/images/image_LICENSE.txt similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/images/image_LICENSE.txt rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/images/image_LICENSE.txt diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/images/lorenz.ico b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/images/lorenz.ico similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/images/lorenz.ico rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/images/lorenz.ico diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/images/splash.jpg b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/images/splash.jpg similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/images/splash.jpg rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/images/splash.jpg diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/lorenz.py b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/lorenz.py similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/lorenz.py rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/lorenz.py diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/lorenz_application.py b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/lorenz_application.py similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/lorenz_application.py rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/lorenz_application.py diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/lorenz_plugin.py b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/lorenz_plugin.py similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/lorenz_plugin.py rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/lorenz_plugin.py diff --git a/examples/plugins/workbench/Lorenz/acme/lorenz/lorenz_ui_plugin.py b/examples/legacy/plugins/workbench/Lorenz/acme/lorenz/lorenz_ui_plugin.py similarity index 100% rename from examples/plugins/workbench/Lorenz/acme/lorenz/lorenz_ui_plugin.py rename to examples/legacy/plugins/workbench/Lorenz/acme/lorenz/lorenz_ui_plugin.py diff --git a/examples/plugins/workbench/Lorenz/run.py b/examples/legacy/plugins/workbench/Lorenz/run.py similarity index 100% rename from examples/plugins/workbench/Lorenz/run.py rename to examples/legacy/plugins/workbench/Lorenz/run.py diff --git a/examples/plugins/tasks/attractors/run.py b/examples/plugins/tasks/attractors/run.py deleted file mode 100644 index 948fa6cd0..000000000 --- a/examples/plugins/tasks/attractors/run.py +++ /dev/null @@ -1,28 +0,0 @@ -# Standard library imports. -import logging - -# Plugin imports. -from envisage.api import CorePlugin -from envisage.ui.tasks.api import TasksPlugin -from attractors.attractors_plugin import AttractorsPlugin - -# Local imports. -from attractors.attractors_application import AttractorsApplication - - -def main(argv): - """ Run the application. - """ - logging.basicConfig(level=logging.WARNING) - - plugins = [CorePlugin(), TasksPlugin(), AttractorsPlugin()] - app = AttractorsApplication(plugins=plugins) - app.run() - - logging.shutdown() - - -if __name__ == "__main__": - import sys - - main(sys.argv) diff --git a/setup.py b/setup.py index 3514302fc..522d5210d 100644 --- a/setup.py +++ b/setup.py @@ -304,7 +304,10 @@ def get_long_description(): entry_points={ "envisage.plugins": [ "envisage.core = envisage.core_plugin:CorePlugin" - ] + ], + "etsdemo_data": [ + "demo_examples = envisage.examples._etsdemo_info:info", + ], }, install_requires=["apptools", "setuptools", "traits"], extras_require={ @@ -317,6 +320,14 @@ def get_long_description(): packages=find_packages(), package_data={ "": ["images/*", "*.ini"], + "envisage.examples": [ + "demo/*", + "demo/*/*", + "demo/*/*/*", + "demo/*/*/*/*", + "demo/*/*/*/*/*", + "demo/*/*/*/*/*/*", + ], "envisage.tests": [ "bad_eggs/*.egg", "eggs/*.egg",