Skip to content

Commit

Permalink
Major shift to direct script execution instead of a helper binary.
Browse files Browse the repository at this point in the history
Importing protos now hijacks control from the script and invokes an internal workflow manager.
Removed the old helper program 'protos_agent.py'
Added the internal workflow manager. It builds the workflow DAG and work queue, then executes all of the work items one by one.
Changed configuration file options around so that config files are now no longer specified in protocol files. They should be taken from either the command line or an environment variable.
Added a topological sort stub to core/workflow. This should return a serialization of all of the tasks in a workflow DAG.
Added explicit documentation for configuration file options.
  • Loading branch information
rdadolf committed Nov 12, 2013
1 parent 661cac7 commit 9fcbe10
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 29 deletions.
20 changes: 20 additions & 0 deletions __init__.py
Expand Up @@ -6,6 +6,8 @@
# Instead, we define it one place, separately, then jump through some hoops
# here to import and define all those functions.

import core.agent

# Pull the Protos API
from core.protos_api import FUNCTIONS

Expand All @@ -20,3 +22,21 @@

# Now clean up our namespace
#del core

################################################################################
# Hijack control
#
# Unlike normal modules, protos doesn't provide functions. It assumes control of
# the program and executes a dependent chain of protocols. The original script
# is merely a convenient way of pointing protos to the last dependency in the
# series.

# This is a way to get the name of the original file caused us to be imported.
# Protos should not be executed from an interactive session (you will not get
# control returned to you).
from __main__ import __file__ as root_protocol_file

core.agent.Agent(root_protocol_file)

# Control does not return, nothing should be below this line.
################################################################################
17 changes: 0 additions & 17 deletions agent/protos_agent.py

This file was deleted.

28 changes: 28 additions & 0 deletions core/agent.py
@@ -0,0 +1,28 @@
# Agent
#
# The work manager, invoked when the first protos library import is called.
# Instead of loading functions, the protos package __init__ function hijacks
# control of the program and invokes this agent instead. The agent then
# builds a complete workflow DAG from static analysis of the original file
# and all of its specified dependencies (through protos.require()). Using
# a topological sort of the DAG, the agent then executes all of the specied
# scripts in order.

import sys
import workflow

class Agent():
def __init__(self, root_protocol_file):
self._flow = workflow.Workflow(root_protocol_file)
self._workq = self._flow.toposort()
self.run() # Does not return

def run(self):
assert self._flow is not None
assert self._workq is not None

for work_item in self._workq:
print 'EXEC: ',work_item

# All execution is complete. Do not return control to the user. Exit.
sys.exit(0)
38 changes: 27 additions & 11 deletions core/config.py
Expand Up @@ -11,17 +11,33 @@
# Dict of dicts
CONFIG_DEFAULTS = {
'project' : {
'repo' : '',
# FIXME: protocol-path deprecated in favor of protocol-dir.
# need to migrate expand_protocol_path once we write
# the software controlling git clones.
'protocol-path' : '', # absolute location of protocol files
'protocol-dir' : '', # relative to project root (git clone root)
},
'log' : {
'repo' : '',
},
}
# Valid types are 'files','git','svn'
'type' : 'files',

# If project-type is 'git' or 'svn', project will be created if it does not
# exist at that location already.
'root' : '',

# The path prefix(es) to search, in order, for protocol files.
# Relative paths are relative to the
'protocol-path' : '',

# Options for project-type=='git':
'git-repo' : '',
# Options
}, 'log' : {
# Valid types are 'files','git','svn'
'type' : 'files',

# If project-type is 'git' or 'svn', project will be created if it does not
# exist at that location already.
'log-root' : '',

# Options for log-type=='git':
'git-repo' : '',
#'git-branch-by-project-revision' : False, FIXME?
},
}

def expand_config_path(s):
'''
Expand Down
2 changes: 1 addition & 1 deletion core/protos_api.py
@@ -1,3 +1,3 @@
# Protos user interface

FUNCTIONS = [ 'config', 'require', 'log', 'var' ]
FUNCTIONS = [ 'config', 'require', 'cache', 'log', 'var' ]
4 changes: 4 additions & 0 deletions core/workflow.py
Expand Up @@ -104,5 +104,9 @@ def build_dependencies(self,given_protocol_file):

return dict([(k,v[1]) for (k,v) in dependencies.items()]), filename_cache

def toposort(self):
warnings.warn('FIXME: replace with actual implementation') # FIXME
return self._deps.keys() # NOT topo-sorted

def __repr__(self):
return str(self._deps)
41 changes: 41 additions & 0 deletions docs/config.md
@@ -0,0 +1,41 @@
# Configuration File Options

----

### Section: `project`
Projects are a collection of related files to be scripted and controlled by a set of protos scripts.

`project-type`
> **values:** `files` `git` `svn`<br>
> **default:** `'files'`<br>
> Describes how the project is stored. If the type is `'git'` or `'svn'`, the project will be cloned or checked out if it doesn't already exist.
`project-root'`
> **values:** absolute path<br>
> **default:** `''`<br>
> The project root directory. Must be an absolute path.
`protocol-path`
> **values:** `:`-separated absolute or relative path prefix strings<br>
> **default:** `''` <br>
> Searched left-to-right. Relative paths are relative to `project-root`. Empty paths between `:`'s or at the beginning or end signify the project directory.
`git-repo`
> **values:** git repository location<br>
> **default:** `''`<br>
> If `project-type` is `git`, the location for the project's git repository. If `project-type` is anything else, the option is ignored. Should be something that git understands, which includes usernames embedded in ssh URLs and absolute pathnames. Relative pathnames are not a good idea.
### Section: `log`

Logs are a complete record of experimental results, archived somewhere permanent.

`log-type`
> **values:** `files` `git` `svn`<br>
> **default:** `files`
> Describes how the log is stored. If the type is `git` or `svn`, the project will be cloned or checked out if it doesn't already exist.
`git-repo`
> **values:** git repository location<br>
> **default:** `''`<br>
> If `log-type` is `git`, the location for the log's git repository. If `log-type` is anything else, the option is ignored. Should be something that git understands, which includes usernames embedded in ssh URLs and absolute pathnames. Relative pathnames are not a good idea.

0 comments on commit 9fcbe10

Please sign in to comment.