abstractfactory/pyblish — pull request #102 by mottosso (2014-09-23 17:11:33+00:00)
Title: Command-line interface and Config 2.0

Hi all,

I've got an initial version of the CLI for Pyblish, capable of running plug-ins via the command-line.

```bat
$ pip install pyblish
$ pyblish publish

SelectCurrentDate...
SelectCurrentWorkingDirectory...
SelectCurrentUser...
ValidateNamingConvention...

--------------------------------------------------------------------------------
Time taken: 0.01s
```

As you'll notice, the executable is installed with pip along with Pyblish and is accessible right after installation.
This will list commands and their description.

```bat
$ pyblish --help
Commands:
config List available config.
install Install Pyblish package via pip.
packages List available packages for Pyblish.
publish Publish instances of path.
test Run Pyblish test-suite.
uninstall Uninstall Pyblish package via pip.

```

Each command have an associated manual.

```bat
$ pyblish publish --help
$ pyblish install --help
```

At the end of the day, the CLI will allow us to test plug-ins without a host, without Python, as well as inspect the various properties of Pyblish and its configuration and discovery mechanism in a simplified manner.

Down the line, we will be able to use thei CLI to perform background and distributed publishing using hosts, such as Maya, as mentioned in #90 and #89.

### CLI and Package Manager

I've also included an experimental Package Control for Pyblish.

```bat
$ pyblish install maya
```

The idea is for it to locate and install integrations/extensions of Pyblish, similar to [Sublime Package Control][sub]. In the future, I'd like us to have a site like this with all available user-contributed, and commercial, extensions of Pyblish.

At the moment, you can install, uninstall and list available extensions.

```bat
$ pyblish uninstall maya
$ pyblish packages
pyblish - quality assurance for content
pyblish_maya - Maya Pyblish package
```

[sub]: https://sublime.wbond.net

# Config 2.0

I've also done some needed maintenance on the configuration aspect which might require your attention in plug-ins that use it.

Previously, configuration was accessed like this:

```python
>>> import pyblish.backend.config
>>> pyblish.backend.config.identifier
"publishable"
```

It was a hacked module which acted like a class, for dot-notation access to attributes.

Now, it is instead accessed like this:

```python
>>> import pyblish.api
>>> pyblish.api.config
{'identifier': 'publishable', ...}
```

Which is a dictionary with super-powers.

```python
>>> pyblish.api.config.default # Get default configuration only
>>> pyblish.api.config.user # Get user configuration only
>>> pyblish.api.config['modify'] = 'config'
>>> pyblish.api.config.reset() # Reset config
```

It is also accessible via the command-line.

```bat
$ pyblish config
Pyblish configuration
identifier = publishable (default)
....
```

Which lists all available variables along with their source, `default` or `user`

#### Config and non-API

When not using the API, the config is accessed like this:

```python
>>> from pyblish import Config
>>> config = Config()
```

`Config` is a singleton, so no matter where or how many times you instantiate it, it will always remain the same and never read from disk more than once, unless you `reset()` it.

```python
>>> config.reset()
```

This is useful if you modify the config at run-time and need to reset it, or if you're user-configuration changes at run-time and you need to pick up the latest changes. We can make use of this in our GUI, for example, but it mainly simplifies testing and de-coupledness.

# Changes to the API

I've also made an important, and breaking change to the API (sorry about this) which was necessary to simplify development and testing.

Before, the API was imported during import of the main package.

```python
>>> import pyblish # Imports API
>>> pyblish.Selector
>>> ...
```

This was very nice for our users, but creates a cyclic dependency on the API and all other modules in the package. Which means that if any module is broken, nothing works.

This is okay, because all modules are meant to be working anyway. However testing is very difficult when modules cannot be isolated from each other and if testing is difficult, code-quality goes down drastically.

Instead, the API is accessed like this:

```python
>>> import pyblish.api
>>> pyblish.api.Selector
```

Fully de-coupled modules at the cost of four extra characters.

# Conclusion

As always, if you have any ideas or suggestions about this update, let's talk about it here!

Best,
Marcus