Improve IJobDefinition documentation

The 'depends' property now clearly states what the value looks like
The 'requires', 'command' 'description' and 'depends' also state
that they may be None

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Make JobDefinition.depends return original data

Instead of pasing the data, return the actual original string.
The parsing logic has been moved to dedicated method

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add JobDefinition.get_direct_dependencies()

This method is the result of moving the parsing away from
JobDefinition.depends. The parsing logic is somewhat forgiving to
allow both comma and space delimited values

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add JobDefinition.get_resourced_dependencies()

This method is similar to get_direct_dependencies() but returns
resource dependencies instead. It can also fail on various syntax
and correctness, as indicated by ResourceProgram

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Update JobDefinition.from_rfc822_record docstring

The docstring now indicates what the arguments must look like and
which keys are required.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add all unit tests for JobDefinition

This patch brings the plainbox.impl.job testing coverage to 100%

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add plainbox.impl.depmgr and assocated tests

This module implements the DependencySolver class with one class method
DependencySolver.resolve_dependencies() that takes a list of jobs
as argument and either throws one of the thee new exceptions or
returns a list of jobs that are safe to run in that order.

The three new exceptions Dependency{Cycle,Missing,Duplicate}Error
indicate that a dependency loop, unresolved dependency or duplicate job
name has been found, respectively. They also carry enough state for
informative error messages or error recovery.

The solver can also consider a subset of jobs to visit. This allows one
to select a few jobs that actually need to run while still taking
advantage of the validation and resource dependency resolution.

The module has 100% test coverage

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add plainbox.impl.rfc822.Origin class

This class can track where a RFC822 record (or other one-dimensional
entity came from). It is used by the rfc822 module to track each parsed
record

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add plainbox.impl.rfc822.RFC822Record class

This class simply binds a data dictionary with a origin object.
It is intended to replace plain dictionaries that were previously
used as record carriers.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Replace dict with RFC822Record

Instead of using plain dictionaries use the new RFC822Record class
to store the data of each record made by load_rfc822_records
and gen_rfc822_records. The record_cls argument was renamed to data_cls
as it no longer influences the class of each returned object.

Each record also has a dummy None origin object attached.

The test suite is update to match this.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add origin tracking to rfc822 parser

The previously None origin object is now created for each record parsed
by gen_rfc822_records(). There are two new local helper functions that
update the internal state and keep track of where each record begins
and ends.

There are no tests for this code yet

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Rename _commit_record() to _commit_key_value_if_needed()

This helper function had a confusing name as it only operated
on the most recently seen key-value pair. With the introduction
of records the name should be updated to reflect actual operation

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add origin field to JobDefinition

The new field allows each job to track its origin. It will be populated
with the new origin data from the RFC822Record class

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Change JobDefinition.from_rfc822_record to require RFC822Record objects

This change allows each job constructed this way to actually get
the origin object. Many tests cases had to be tediously updated as
the values passed no can longer be plain dictionaries.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Improve mk-venv.sh script

The script now does basic checks for missing packages and
instructs the user on how to install them.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Update checkbox submodule to latest bzr trunk

This fixes the touchpad job "product.CATEGORY" issue that was actually
found with plainbox resource validation system

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add additional tests to job module

This is just a sanity test that single word won't get exploded
between each letter.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
New box / prototype UI code

This monolithic patch may be further broken down if necessary.
It brings several big changes:

 - the use of dependency resolver
 - the set of special options to list jobs, expressions and print
   dot graphs of the selected jobs
 - the ability to run in 'dry-run' mode
 - the output is changed to look more consistent than it did before

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Add mk-interesting-graphs.sh

This simple script renders a number of svg graphs based on the known
jobs that are parsed and read from checkbox

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
Merge branch 'feature/dependency-manager' into develop