Basic invocation is this:
devenv targetwhere target is the name of the project you need to run.
Devenv
would run this project and all of it's dependencies in a detached screen
session with the name devenv.
Each of the projects would run in a separate window within this session.
You can attach to that session and see how it's going, using, for example,
screen -drSee
screen
documentation for more information.
You can destroy the session and kill all processes running within it with a simple command
devenv -kor you can specify which project to kill, while letting others run:
devenv -k target1 target2...
You can run several projects (along with their dependencies) at once:
devenv target1 target2
If the screen session already exists, you can add projects to it with a -a
switch:
devenv -a target3That way
devenv
won't try to start a project that is already running.
You can also disable dependency tracking completely:
devenv -j targetIn this case, only the projects (targets) listed in the command line would run.
It's possible to use a different session name:
devenv -s session_name targetThis switch can be combined with
-k
.
devenv
uses single configuration file, which lists all the projects with all steps necessary to run those.
By default, this file is named .devenv.yml
and is placed in the user's home directory.
You can specify another configuration file with the -f
switch:
devenv -f config_file.yml targetThis switch can be combined with all other parameters listed above.
Configuration file uses YAML syntax. The reader is supposed to be familiar with YAML.
basedir: projects/main/src init: setup_vpn -u current_user targets: project_1: directory: pr1 shell: run_project -z funny wait: port: 8080 pause: 60 init: init_projects -x or_not title: main error: err_pr_1 project_2: directory: pr2 dependencies: - project_1 - project_3 ...
The basedir
parameter specifies the directory within which all projects reside.
This can be an absolute or relative path.
If it's relative, then the base directory for it is the directory in which the configuration file is found.
init
is a shell command that should be run before all the projects.
It's run in the same directory in which devenv
is invoked.
targets
map lists all projects that devenv
can run.
Each project corresponds to one entry in this map, with the name being the intended name of a project, and the value being another map, listing all the parameters of it.
The directory
parameter is the directory in which the project should be running.
It can be an absolute path, or a path relative to the basedir
above.
shell
is a shell command which runs the project.
It is executed in the detached screen
session.
It's output is not shown, unless you attach to that session.
wait
is a list of things devenv
would be waiting for, while the project starts.
Only when all of them are present, devenv
would consider the project running.
Currently the only thing that devenv
can wait for is one port with arbitrary number, given in the port
parameter.
After the project is successfully running, devenv
would pause for the number of seconds, specified in the pause
parameter.
If that is not necessary, this parameter should be omitted.
After that timeout has passed, or, if it's absent, after the wait is over and the project is running, the command specified in the init
parameter is run.
It is not run in the screen
session, and would normally communicate with the project in some other way.
Each project runs in it's own screen
window within one session, and that window has a title given in the title
parameter.
If this parameter is omitted, the title of the window would be the same as the name of the project.
error
is a file that devenv
creates in the project directory and removes after the project finishes running.
It helps determine if the project finished prematurely, or if it's already running.
Omitting this parameter would result in devenv
assuming no errors occured while starting the project, and that the project wasn't already running before.
devenv
tracks dependencies between projects.
The dependencies
field is a list of other projects that should be run before this one.
No projects would run if a circular dependency is detected, and an error would be reported.
devenv
supports two features allowing to modify projects' behaviour.
In the command line any number of override names can be listed using -o
switch:
devenv -o override_1 -o override_2 targetEach time when
devenv
reads the value of any key in the configuration file, it checks if the map, in which this key is, has an overrides
key.
If such a key is present, and the corresponding value is a map, then it's elements are given a chance to override the value that is being fetched.
Only the overrides with names listed in the command line are used.
Those that do not provide a new value for that key are ignored.
If there are several possible overrides, then the one with the name being the last in the command line is used.
Example:
... shell: run_project wait: port: 8080 overrides: fast: shell: run_project --skip-slow-checks and: shell: run_project --extra-safe port: 8081 furious: port: 8888Normally,
devenv
would start the project using the command run_project
, and wait for the port 8080
to become open.
If, however, it is run as devenv -o fast
, then it would use the command run_project --skip-slow-checks
to start the project,
but it would still wait for the port 8080
.
If it is run as devenv -o fast -o and -o furious
, then the command run_project --extra-safe
would be used,
but devenv
would wait for the port 8888
instead.
Overrides only apply to the same YAML map they are members of; they do not change anything in the subtrees below that map, or in other maps, not related to that one.
Each map can contain it's own set of overrides.
Not all overrides must be listed in the overrides
map; those that are not listed are assumed to be empty.
There is no possible way to limit overrides to one particular project or other kind of map. All overrides specified in the command line are applied to everything in the configuration file.
All string parameters in the configuration file can use variables. The variable name is enclosed in curly braces: {var_name}
.
Each YAML map can provide a variables
map, listing the values of all variables.
Those values also should be strings.
Example:
... shell: run_project --listen-to {port_number} wait: port: {port_number} variables: port_number: 8080In this example, command line
run_project --listen-to 8080
would be used to start the project,
and devenv
would wait for the port 8080
to become open.
Unlike overrides, variables can be inherited: variable is not only substituted in any string that is in the same map, but also in the whole subtree under it. Variables specified on the deeper level take precedence:
targets: pr_1: shell: run_1 {arg} ... pr_2: shell: run_2 {arg} ... pr_3: shell: run_3 {arg} variables: arg: foo ... variables: arg: barIn this example, targets
pr_1
and pr_2
would be started with command lines run_1 bar
and run_2 bar
respectively,
but the target pr_3
would use the command line run_3 foo
instead.
... overrides: name: foo: bar{baz} overrides: name: foo: quux variables baz: qazonly the literal string
bar{baz}
would be used as an override for the key foo
.
Internal overrides
and variables
keys would be regarded as unrelated overrides with names overrides
and variables
.
On the other hand, there is nothing wrong with values of overrides containing overrides and variables of their own:
... overrides: foo: shell: run_1 overrides: bar: shell: run_2In this case, if an override name
foo
is given in the command line, command run_1
would be used,
but if both foo
and bar
are given, command run_2
would be used instead.
If bar
is given in the command line, but foo
is not, no overrides would be used, unless bar
is mentioned elsewhere in the file.
Overrides also can refer to the variables that would be used even without override:
... shell: run_project {foo} overrides: quick: shell: run_project --quick {foo} variables foo: barIf no override name is given, command line
run_project bar
would be used,
but if override quick
is in effect, it would be run_project --quick bar
.
Variables, on the other hand, can't refer to other variables. Their values are substituted literally, with no further processing.
... shell: run {foo} variables: foo: {bar} bar: bazIn this case the command line would be
run {bar}
, with variable bar
not being substituted.
Variables, however, can use overrides.
... shell: run {foo} overrides: bar: shell: run_bar {foo} variables foo: baz overrides: quux: foo: qazNormally, overrides would be ignored, and the command
run baz
used.
If override bar
is in effect, the command would be run_bar baz
.
If override quux
is in effect, the command would be run qaz
And, at last, if both overrides are listed on the command line, like devenv -o bar -o quux
, then it would be run_bar qaz
.
-k
switch.