fig 0.1.3 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +67 -19
- data/bin/fig +21 -13
- data/bin/fig-download +20 -0
- data/lib/fig/environment.rb +17 -16
- data/lib/fig/options.rb +39 -9
- data/lib/fig/os.rb +33 -5
- data/lib/fig/repository.rb +11 -2
- data/spec/fig_spec.rb +58 -13
- metadata +17 -9
data/README.md
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
Description
|
2
2
|
===========
|
3
3
|
|
4
|
-
Fig is a utility for
|
4
|
+
Fig is a utility for configuring environments and managing dependencies across a team of developers. You give it a list of packages and a shell command to run; it creates an environment that includes those packages, then executes the shell command in it (the caller's environment is not affected).
|
5
5
|
|
6
|
-
|
6
|
+
An "environment" in fig is just a set of environment variables. A "package" is a collection of files, plus some metadata describing what environment variables should be modified when the package is included.
|
7
7
|
|
8
|
-
|
8
|
+
Developers can a use package files to specify the list of dependencies to use for different tasks. This file will typically be versioned along with the rest of the source files. This ensures that all developers on a team are using the same environemnts.
|
9
|
+
|
10
|
+
Packages exist in two places: a "local" repository in the user's home directory, and a "remote" repository on a server somewhere that is shared by a team. Fig will automatically download packages from the remote repository and install them in the local repository, when needed.
|
11
|
+
|
12
|
+
Fig is similar to a lot of other package/dependnency managment tools. In particular, it steals a lot of ideas from Apache Ivy and Debian APT. However, unlike Ivy, fig is meant to be lightweight (no XML, no JVM startup time), language agnostic (Java doesn't get preferential treatment), and work with executables as well as libraries. And unlike APT, fig is meant to be cross platform (Windows support is coming) and project-oriented.
|
9
13
|
|
10
14
|
Installation
|
11
15
|
============
|
@@ -63,27 +67,27 @@ Fig also supports the following options, which don't require a fig environment.
|
|
63
67
|
Examples
|
64
68
|
========
|
65
69
|
|
66
|
-
Fig lets you
|
70
|
+
Fig lets you configure environments three different ways:
|
67
71
|
|
68
72
|
* From the command line
|
69
|
-
* From a ".fig" file in the current directory
|
70
|
-
* From packages
|
73
|
+
* From a "package.fig" file in the current directory
|
74
|
+
* From packages included indirectly via one of the previous two methods
|
71
75
|
|
72
76
|
### Command Line ###
|
73
77
|
|
74
|
-
So to get started, let's trying defining an environment variable via the command line and executing a command in the
|
78
|
+
So to get started, let's trying defining an environment variable via the command line and executing a command in the newenvironment. We'll set the "GREETING" variable to "Hello", then run a command that uses that variable:
|
75
79
|
|
76
80
|
$ fig -s GREETING=Hello -- echo "\$GREETING, World"
|
77
81
|
Hello, World
|
78
82
|
|
79
|
-
|
83
|
+
Note that you need to put a slash before the dollar sign, otherwise the shell will evaluate the environment variable before it ever gets to fig.
|
80
84
|
|
81
|
-
Also note that when running fig, the original environment
|
85
|
+
Also note that when running fig, the original environment isn't affected:
|
82
86
|
|
83
87
|
$ echo $GREETING
|
84
88
|
<nothing>
|
85
89
|
|
86
|
-
Fig also lets you append environment variables, using the system-specified path separator (e.g. colon on unix, semicolon on windows). This is useful for adding directories to the PATH, LD_LIBRARY_PATH, etc. For example, let's create a "bin" directory, add a shell script to it, then include it in the PATH:
|
90
|
+
Fig also lets you append environment variables, using the system-specified path separator (e.g. colon on unix, semicolon on windows). This is useful for adding directories to the PATH, LD_LIBRARY_PATH, CLASSPATH, etc. For example, let's create a "bin" directory, add a shell script to it, then include it in the PATH:
|
87
91
|
|
88
92
|
$ mkdir bin
|
89
93
|
$ echo "echo \$GREETING, World" > bin/hello
|
@@ -93,14 +97,14 @@ Fig also lets you append environment variables, using the system-specified path
|
|
93
97
|
|
94
98
|
### Fig Files ###
|
95
99
|
|
96
|
-
You can also specify environment modifiers in files. Fig looks for a file called ".fig" in the current directory, and automatically processes it. So we can implement the previous example by creating a ".fig" file that looks like:
|
100
|
+
You can also specify environment modifiers in files. Fig looks for a file called "package.fig" in the current directory, and automatically processes it. So we can implement the previous example by creating a "package.fig" file that looks like:
|
97
101
|
|
98
102
|
config default
|
99
103
|
set GREETING=Hello
|
100
|
-
append PATH
|
104
|
+
append PATH=@/bin
|
101
105
|
end
|
102
106
|
|
103
|
-
Then we can just run:
|
107
|
+
The '@' symbol represents the directory that the "package.fig" file is in (this example would still work if we just used "bin", but later on when we publish our project to the shared repository we'll definitely need the '@'). Then we can just run:
|
104
108
|
|
105
109
|
$ fig -- hello
|
106
110
|
Hello, World
|
@@ -109,12 +113,12 @@ A single fig file can have multiple configurations:
|
|
109
113
|
|
110
114
|
config default
|
111
115
|
set GREETING=Hello
|
112
|
-
append PATH
|
116
|
+
append PATH=@/bin
|
113
117
|
end
|
114
118
|
|
115
119
|
config french
|
116
120
|
set GREETING=Bonjour
|
117
|
-
append PATH
|
121
|
+
append PATH=@/bin
|
118
122
|
end
|
119
123
|
|
120
124
|
Configurations other than "default" can be specified using the "-c" option:
|
@@ -124,11 +128,11 @@ Configurations other than "default" can be specified using the "-c" option:
|
|
124
128
|
|
125
129
|
### Packages ###
|
126
130
|
|
127
|
-
Now let's say we want to share our little script with the rest of the team by bundling it into a package. The first thing
|
131
|
+
Now let's say we want to share our little script with the rest of the team by bundling it into a package. The first thing we need to do is specify the location of the remote repository by defining the FIG_REMOTE_URL environment variable. If you just want to play around with fig, you can have it point to localhost:
|
128
132
|
|
129
133
|
$ export FIG_REMOTE_URL=ssh://localhost`pwd`/remote
|
130
134
|
|
131
|
-
Before we publish our package, we'll need to tell fig which files we want to include. We do this by using the "resource" statement in our ".fig" file:
|
135
|
+
Before we publish our package, we'll need to tell fig which files we want to include. We do this by using the "resource" statement in our "package.fig" file:
|
132
136
|
|
133
137
|
resource bin/hello
|
134
138
|
|
@@ -138,9 +142,53 @@ Now we can share the package with the rest of the team by using the "--publish"
|
|
138
142
|
|
139
143
|
$ fig --publish hello/1.0.0
|
140
144
|
|
141
|
-
The "hello/1.0.0" string represents the name of the package and the version number. Once the package has been published, we can include it in other environments by using the "-i"
|
145
|
+
The "hello/1.0.0" string represents the name of the package and the version number. Once the package has been published, we can include it in other environments by using the "-i" or "--include" option (I'm going to move the "package.fig" file out of the way first, so that fig doesn't automatically process it.):
|
146
|
+
|
147
|
+
$ mv package.fig package.bak
|
148
|
+
$ fig -u -i hello/1.0.0 -- hello
|
149
|
+
...downloading files...
|
150
|
+
Hello, World
|
151
|
+
|
152
|
+
The "-u" (or "--update") option tells fig to check the remote repository for packages if they aren't already installed locally (fig will never make any network connections unless this option is specified). Once the packages are downloaded, we can run the same command without the "-u" option:
|
153
|
+
|
154
|
+
$ fig -i hello/1.0.0 -- hello
|
155
|
+
Hello, World
|
156
|
+
|
157
|
+
Also, when including a package, you can specify a particular configuration by appending it to the package name using a colon:
|
158
|
+
|
159
|
+
$ fig -i hello/1.0.0:french -- hello
|
160
|
+
Hello, World
|
161
|
+
|
162
|
+
### Retrieves ###
|
163
|
+
|
164
|
+
By default, the resources associated with a package live in the fig home directory, which defaults to "~/.fighome". This doesn't always play nicely with IDE's however, so fig gives you a way to copy resources from the repository to the current directory. To do this you add "retrieve" statements to your "package.fig" file.
|
165
|
+
|
166
|
+
For example, let's create a package that contains a library for the "foo" programming language. First we'll define a "package.fig" file:
|
167
|
+
|
168
|
+
config default
|
169
|
+
append FOOPATH=lib/hello.foo
|
170
|
+
end
|
171
|
+
|
172
|
+
Then:
|
173
|
+
|
174
|
+
$ mkdir lib
|
175
|
+
$ echo "print 'hello'" > lib/hello.foo
|
176
|
+
$ fig --publish hello-lib/3.2.1
|
177
|
+
|
178
|
+
Now we'll move to a different directory (or delete the current "package.fig" file) and create a new "package.fig" file:
|
179
|
+
|
180
|
+
retrieve FOOPATH->lib/[package]
|
181
|
+
config default
|
182
|
+
include hello-lib/3.2.1
|
183
|
+
end
|
184
|
+
|
185
|
+
When we do an update, all resources in the FOOPATH will be copied into the lib directory, into a subdirectory that matches the package name:
|
142
186
|
|
143
|
-
|
187
|
+
$ fig -u
|
188
|
+
...downloading...
|
189
|
+
...retrieving...
|
190
|
+
$ cat lib/hello-lib/hello.foo
|
191
|
+
print 'hello'
|
144
192
|
|
145
193
|
Community
|
146
194
|
=========
|
data/bin/fig
CHANGED
@@ -57,20 +57,16 @@ os = OS.new
|
|
57
57
|
repos = Repository.new(os, File.expand_path(File.join(options[:home], 'repos')), remote_url, remote_user)
|
58
58
|
env = Environment.new(os, repos, vars)
|
59
59
|
|
60
|
-
options[:
|
61
|
-
|
62
|
-
env.include_config(nil, package_name, config_name, version_name)
|
60
|
+
options[:modifiers].each do |modifier|
|
61
|
+
env.apply_config_statement(nil, modifier)
|
63
62
|
end
|
64
63
|
|
65
|
-
|
66
|
-
|
64
|
+
if File.exist?(".fig")
|
65
|
+
$stderr.puts "The '.fig' file is deprecated. Please rename to 'package.fig'"
|
66
|
+
exit 1
|
67
67
|
end
|
68
68
|
|
69
|
-
|
70
|
-
env.append_variable(nil, name_val[0], name_val[1])
|
71
|
-
end
|
72
|
-
|
73
|
-
DEFAULT_FIG_FILE = '.fig'
|
69
|
+
DEFAULT_FIG_FILE = 'package.fig'
|
74
70
|
|
75
71
|
input = nil
|
76
72
|
if options[:input] == :none
|
@@ -88,6 +84,11 @@ else
|
|
88
84
|
end
|
89
85
|
end
|
90
86
|
|
87
|
+
options[:cleans].each do |descriptor|
|
88
|
+
package_name, version_name = descriptor.split('/')
|
89
|
+
repos.clean(package_name, version_name)
|
90
|
+
end
|
91
|
+
|
91
92
|
if input
|
92
93
|
package = Parser.new.parse_package(nil, nil, ".", input)
|
93
94
|
if options[:retrieve]
|
@@ -119,8 +120,14 @@ if options[:publish]
|
|
119
120
|
if package_name.nil? || version_name.nil?
|
120
121
|
raise "Please specify a package name and a version name"
|
121
122
|
end
|
122
|
-
|
123
|
-
|
123
|
+
if not options[:modifiers].empty?
|
124
|
+
publish_statements = options[:resources] + options[:archives] + [Configuration.new("default", options[:modifiers])]
|
125
|
+
elsif not package.publish_statements.empty?
|
126
|
+
publish_statements = package.publish_statements
|
127
|
+
else
|
128
|
+
fail "Nothing to publish"
|
129
|
+
end
|
130
|
+
repos.publish_package(publish_statements, package_name, version_name)
|
124
131
|
elsif options[:echo]
|
125
132
|
puts env[options[:echo]]
|
126
133
|
elsif argv[0] == "-"
|
@@ -130,6 +137,7 @@ elsif argv[0]
|
|
130
137
|
package_name, config_name, version_name = parse_descriptor(argv.shift)
|
131
138
|
env.include_config(package, package_name, config_name, version_name)
|
132
139
|
env.execute_config(package, package_name, config_name, nil) { |cmd| shell_exec cmd }
|
133
|
-
|
140
|
+
elsif input
|
134
141
|
env.execute_config(package, nil, options[:config], nil) { |cmd| shell_exec cmd }
|
135
142
|
end
|
143
|
+
|
data/bin/fig-download
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# todo copied from os.rb
|
4
|
+
NOT_MODIFIED = 3
|
5
|
+
NOT_FOUND = 4
|
6
|
+
SUCCESS = 0
|
7
|
+
|
8
|
+
timestamp = ARGV[0].to_i
|
9
|
+
path = ARGV[1]
|
10
|
+
|
11
|
+
exit NOT_FOUND unless File.exist?(path)
|
12
|
+
exit NOT_MODIFIED if File.mtime(path).to_i <= timestamp
|
13
|
+
|
14
|
+
File.open(path) do |file|
|
15
|
+
while bytes = file.read(4096) do
|
16
|
+
$stdout.write(bytes)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
exit SUCCESS
|
data/lib/fig/environment.rb
CHANGED
@@ -54,6 +54,23 @@ module Fig
|
|
54
54
|
result
|
55
55
|
end
|
56
56
|
|
57
|
+
def apply_config_statement(base_package, statement)
|
58
|
+
case statement
|
59
|
+
when Path
|
60
|
+
append_variable(base_package, statement.name, statement.value)
|
61
|
+
when Set
|
62
|
+
set_variable(base_package, statement.name, statement.value)
|
63
|
+
when Include
|
64
|
+
include_config(base_package, statement.package_name, statement.config_name, statement.version_name)
|
65
|
+
when Command
|
66
|
+
# ignore
|
67
|
+
else
|
68
|
+
fail "Unexpected statement: #{statement}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
57
74
|
def include_config(base_package, package_name, config_name, version_name)
|
58
75
|
package = lookup_package(package_name || base_package.package_name, version_name)
|
59
76
|
apply_config(package, config_name || "default")
|
@@ -73,8 +90,6 @@ module Fig
|
|
73
90
|
end
|
74
91
|
end
|
75
92
|
|
76
|
-
private
|
77
|
-
|
78
93
|
def with_environment
|
79
94
|
old_env = {}
|
80
95
|
begin
|
@@ -85,20 +100,6 @@ module Fig
|
|
85
100
|
end
|
86
101
|
end
|
87
102
|
|
88
|
-
def apply_config_statement(base_package, statement)
|
89
|
-
case statement
|
90
|
-
when Path
|
91
|
-
append_variable(base_package, statement.name, statement.value)
|
92
|
-
when Set
|
93
|
-
set_variable(base_package, statement.name, statement.value)
|
94
|
-
when Include
|
95
|
-
include_config(base_package, statement.package_name, statement.config_name, statement.version_name)
|
96
|
-
when Command
|
97
|
-
# ignore
|
98
|
-
else
|
99
|
-
fail "Unexpected statement: #{statement}"
|
100
|
-
end
|
101
|
-
end
|
102
103
|
|
103
104
|
def lookup_package(package_name, version_name)
|
104
105
|
package = @packages[package_name]
|
data/lib/fig/options.rb
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
require 'optparse'
|
2
|
+
require 'fig/package'
|
2
3
|
|
3
4
|
module Fig
|
5
|
+
def parse_descriptor(descriptor)
|
6
|
+
# todo should use treetop for these:
|
7
|
+
package_name = descriptor =~ /^([^:\/]+)/ ? $1 : nil
|
8
|
+
config_name = descriptor =~ /:([^:\/]+)/ ? $1 : nil
|
9
|
+
version_name = descriptor =~ /\/([^:\/]+)/ ? $1 : nil
|
10
|
+
return package_name, config_name, version_name
|
11
|
+
end
|
12
|
+
|
4
13
|
def parse_options(argv)
|
5
14
|
options = {}
|
6
15
|
|
@@ -22,26 +31,47 @@ module Fig
|
|
22
31
|
opts.on('-c', '--config CFG', 'name of configuration to apply') { |config| options[:config] = config }
|
23
32
|
|
24
33
|
options[:echo] = nil
|
25
|
-
opts.on('-g', '--
|
34
|
+
opts.on('-g', '--get VAR', 'print value of environment variable') { |echo| options[:echo] = echo }
|
26
35
|
|
27
36
|
options[:publish] = nil
|
28
37
|
opts.on('--publish PKG', 'install package in local and remote repositories') { |publish| options[:publish] = publish }
|
29
38
|
|
39
|
+
options[:resources] =[]
|
40
|
+
opts.on('--resource PATH', 'resource to include in package (when using --publish)') do |path|
|
41
|
+
options[:resources] << Resource.new(path)
|
42
|
+
end
|
43
|
+
|
44
|
+
options[:archives] =[]
|
45
|
+
opts.on('--archive PATH', 'archive to include in package (when using --publish)') do |path|
|
46
|
+
options[:archives] << Archive.new(path)
|
47
|
+
end
|
48
|
+
|
30
49
|
options[:list] = false
|
31
50
|
opts.on('--list', 'list packages in local repository') { options[:list] = true }
|
32
51
|
|
33
|
-
options[:
|
34
|
-
opts.on('
|
52
|
+
options[:cleans] = []
|
53
|
+
opts.on('--clean PKG', 'remove package from local repository') { |descriptor| options[:cleans] << descriptor }
|
54
|
+
|
55
|
+
options[:modifiers] = []
|
56
|
+
|
57
|
+
opts.on('-i', '--include PKG', 'include package in environment') do |descriptor|
|
58
|
+
package_name, config_name, version_name = parse_descriptor(descriptor)
|
59
|
+
options[:modifiers] << Include.new(package_name, config_name, version_name)
|
60
|
+
end
|
35
61
|
|
36
|
-
|
37
|
-
|
62
|
+
opts.on('-s', '--set VAR=VAL', 'set environment variable') do |var_val|
|
63
|
+
var, val = var_val.split('=')
|
64
|
+
options[:modifiers] << Set.new(var, val)
|
65
|
+
end
|
38
66
|
|
39
|
-
|
40
|
-
|
67
|
+
opts.on('-p', '--append VAR=VAL', 'append environment variable') do |var_val|
|
68
|
+
var, val = var_val.split('=')
|
69
|
+
options[:modifiers] << Path.new(var, val)
|
70
|
+
end
|
41
71
|
|
42
72
|
options[:input] = nil
|
43
|
-
opts.on('--
|
44
|
-
opts.on('--no-file', 'fig file
|
73
|
+
opts.on('--file FILE', 'fig file to read (use - for stdin)') { |path| options[:input] = path }
|
74
|
+
opts.on('--no-file', 'ignore .fig file in current directory') { |path| options[:input] = :none }
|
45
75
|
|
46
76
|
options[:home] = ENV['FIG_HOME'] || File.expand_path("~/.fighome")
|
47
77
|
end
|
data/lib/fig/os.rb
CHANGED
@@ -2,6 +2,8 @@ require 'fileutils'
|
|
2
2
|
require 'ftools'
|
3
3
|
require 'uri'
|
4
4
|
require 'net/http'
|
5
|
+
require 'open4'
|
6
|
+
require 'tempfile'
|
5
7
|
|
6
8
|
module Fig
|
7
9
|
class OS
|
@@ -25,6 +27,10 @@ module Fig
|
|
25
27
|
File.open(path, "w") { |f| f << content }
|
26
28
|
end
|
27
29
|
|
30
|
+
SUCCESS = 0
|
31
|
+
NOT_MODIFIED = 3
|
32
|
+
NOT_FOUND = 4
|
33
|
+
|
28
34
|
def download(url, path)
|
29
35
|
FileUtils.mkdir_p(File.dirname(path))
|
30
36
|
uri = URI.parse(url)
|
@@ -49,13 +55,35 @@ module Fig
|
|
49
55
|
end
|
50
56
|
when "ssh"
|
51
57
|
# TODO need better way to do conditional download
|
52
|
-
timestamp = `ssh #{uri.user + '@' if uri.user}#{uri.host} "ruby -e 'puts File.mtime(\\"#{uri.path}\\").to_i'"`.to_i
|
53
|
-
|
58
|
+
# timestamp = `ssh #{uri.user + '@' if uri.user}#{uri.host} "ruby -e 'puts File.mtime(\\"#{uri.path}\\").to_i'"`.to_i
|
59
|
+
out = nil
|
60
|
+
timestamp = File.exist?(path) ? File.mtime(path).to_i : 0
|
61
|
+
tempfile = Tempfile.new("tmp")
|
62
|
+
IO.popen("ssh #{uri.user + '@' if uri.user}#{uri.host} \"fig-download #{timestamp} #{uri.path}\"") do |io|
|
63
|
+
first = true
|
64
|
+
while bytes = io.read(4096)
|
65
|
+
if first
|
66
|
+
$stderr.puts "downloading #{url}"
|
67
|
+
first = false
|
68
|
+
end
|
69
|
+
tempfile << bytes
|
70
|
+
end
|
71
|
+
end
|
72
|
+
tempfile.close
|
73
|
+
case $?.exitstatus
|
74
|
+
when NOT_MODIFIED
|
75
|
+
tempfile.delete
|
54
76
|
return false
|
55
|
-
|
56
|
-
|
57
|
-
|
77
|
+
when NOT_FOUND
|
78
|
+
tempfile.delete
|
79
|
+
raise "File not found: #{uri}"
|
80
|
+
when SUCCESS
|
81
|
+
FileUtils.mv(tempfile.path, path)
|
58
82
|
return true
|
83
|
+
else
|
84
|
+
tempfile.delete
|
85
|
+
$stderr.puts "Unable to download file: #{$?.exitstatus}"
|
86
|
+
exit 1
|
59
87
|
end
|
60
88
|
else
|
61
89
|
raise "Unknown protocol: #{url}"
|
data/lib/fig/repository.rb
CHANGED
@@ -10,6 +10,12 @@ module Fig
|
|
10
10
|
@parser = Parser.new
|
11
11
|
end
|
12
12
|
|
13
|
+
def clean(package_name, version_name)
|
14
|
+
dir = File.join(@local_repository_dir, package_name)
|
15
|
+
dir = File.join(dir, version_name) if version_name
|
16
|
+
FileUtils.rm_rf(dir)
|
17
|
+
end
|
18
|
+
|
13
19
|
def list_packages
|
14
20
|
results = []
|
15
21
|
@os.list(@local_repository_dir).each do |package_name|
|
@@ -47,7 +53,7 @@ module Fig
|
|
47
53
|
end
|
48
54
|
@os.write(fig_file, content.join("\n"))
|
49
55
|
@os.upload(fig_file, remote_fig_file_for_package(package_name, version_name), @remote_repository_user)
|
50
|
-
update_package(package_name, version_name)
|
56
|
+
# update_package(package_name, version_name)
|
51
57
|
end
|
52
58
|
|
53
59
|
def bundle_resources(package_statements)
|
@@ -97,7 +103,10 @@ module Fig
|
|
97
103
|
end
|
98
104
|
|
99
105
|
def read_package_from_file(file_name, package_name, version_name)
|
100
|
-
|
106
|
+
if not @os.exist?(file_name)
|
107
|
+
$stderr.puts "Package not found: #{package_name}/#{version_name}"
|
108
|
+
exit 1
|
109
|
+
end
|
101
110
|
modified_time = @os.mtime(file_name)
|
102
111
|
content = @os.read(file_name)
|
103
112
|
@parser.parse_package(package_name, version_name, File.dirname(file_name), content)
|
data/spec/fig_spec.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rubygems'
|
4
|
+
require 'open4'
|
4
5
|
require 'fileutils'
|
5
6
|
|
6
7
|
FIG_HOME = File.expand_path(File.dirname(__FILE__) + '/../tmp/fighome')
|
@@ -15,13 +16,24 @@ puts ENV['FIG_REMOTE_URL']
|
|
15
16
|
FIG_EXE = File.expand_path(File.dirname(__FILE__) + '/../bin/fig')
|
16
17
|
|
17
18
|
def fig(args, input=nil)
|
18
|
-
args = "--
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
args = "--file - #{args}" if input
|
20
|
+
out = nil
|
21
|
+
err = nil
|
22
|
+
status = Open4::popen4("#{FIG_EXE} #{args}") do |pid, stdin, stdout, stderr|
|
23
|
+
if input
|
24
|
+
stdin.puts input
|
25
|
+
stdin.close
|
26
|
+
end
|
27
|
+
err = stderr.read.strip
|
28
|
+
out = stdout.read.strip
|
29
|
+
if err != ""
|
30
|
+
$stderr.puts err
|
31
|
+
end
|
23
32
|
end
|
24
|
-
|
33
|
+
if $?.exitstatus != 0
|
34
|
+
raise "Command failed: #{$?.exitstatus}"
|
35
|
+
end
|
36
|
+
return out, err
|
25
37
|
end
|
26
38
|
|
27
39
|
describe "Fig" do
|
@@ -65,22 +77,55 @@ describe "Fig" do
|
|
65
77
|
end
|
66
78
|
END
|
67
79
|
puts fig('--publish foo/1.2.3', input)
|
68
|
-
fig('-i foo/1.2.3 -g FOO').should ==
|
80
|
+
fig('-u -i foo/1.2.3 -g FOO')[0].should == 'BAR'
|
69
81
|
end
|
70
82
|
|
71
83
|
it "publish resource to remote repository" do
|
72
84
|
FileUtils.rm_rf(FIG_HOME)
|
73
85
|
FileUtils.rm_rf(FIG_REMOTE_DIR)
|
74
|
-
FileUtils.mkdir_p("bin")
|
75
|
-
File.open("bin/hello", "w") { |f| f << "echo bar" }
|
76
|
-
fail unless system "chmod +x bin/hello"
|
86
|
+
FileUtils.mkdir_p("tmp/bin")
|
87
|
+
File.open("tmp/bin/hello", "w") { |f| f << "echo bar" }
|
88
|
+
fail unless system "chmod +x tmp/bin/hello"
|
77
89
|
input = <<-END
|
78
|
-
resource bin/hello
|
90
|
+
resource tmp/bin/hello
|
79
91
|
config default
|
80
|
-
append PATH=@/bin
|
92
|
+
append PATH=@/tmp/bin
|
81
93
|
end
|
82
94
|
END
|
83
95
|
puts fig('--publish foo/1.2.3', input)
|
84
96
|
fig('-u -i foo/1.2.3 -- hello')[0].should == 'bar'
|
85
97
|
end
|
98
|
+
|
99
|
+
it "publish resource to remote repository using command line" do
|
100
|
+
FileUtils.rm_rf(FIG_HOME)
|
101
|
+
FileUtils.rm_rf(FIG_REMOTE_DIR)
|
102
|
+
FileUtils.mkdir_p("tmp/bin")
|
103
|
+
File.open("tmp/bin/hello", "w") { |f| f << "echo bar" }
|
104
|
+
fail unless system "chmod +x tmp/bin/hello"
|
105
|
+
puts fig('--publish foo/1.2.3 --resource tmp/bin/hello --append PATH=@/tmp/bin')
|
106
|
+
fig('-u -i foo/1.2.3 -- hello')[0].should == 'bar'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "retrieve resource" do
|
110
|
+
FileUtils.rm_rf(FIG_HOME)
|
111
|
+
FileUtils.rm_rf(FIG_REMOTE_DIR)
|
112
|
+
FileUtils.rm_rf("tmp")
|
113
|
+
FileUtils.mkdir_p("tmp/lib")
|
114
|
+
File.open("tmp/lib/hello", "w") { |f| f << "some library" }
|
115
|
+
input = <<-END
|
116
|
+
resource tmp/lib/hello
|
117
|
+
config default
|
118
|
+
append FOOPATH=@/tmp/lib/hello
|
119
|
+
end
|
120
|
+
END
|
121
|
+
puts fig('--publish foo/1.2.3', input)
|
122
|
+
input = <<-END
|
123
|
+
retrieve FOOPATH->tmp/lib2/[package]
|
124
|
+
config default
|
125
|
+
include foo/1.2.3
|
126
|
+
end
|
127
|
+
END
|
128
|
+
fig('-u', input)
|
129
|
+
File.read("tmp/lib2/foo/hello").should == "some library"
|
130
|
+
end
|
86
131
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fig
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Foemmel
|
@@ -9,8 +9,8 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
13
|
-
default_executable:
|
12
|
+
date: 2010-01-07 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: polyglot
|
@@ -42,14 +42,21 @@ dependencies:
|
|
42
42
|
- !ruby/object:Gem::Version
|
43
43
|
version: 1.2.9
|
44
44
|
version:
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: open4
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.0.1
|
54
|
+
version:
|
55
|
+
description: Fig is a utility for configuring environments and managing dependencies across a team of developers. You give it a list of packages and a shell command to run; it creates an environment that includes those packages, then executes the shell command in it (the caller's environment is not affected).
|
50
56
|
email: git@foemmel.com
|
51
57
|
executables:
|
52
58
|
- fig
|
59
|
+
- fig-download
|
53
60
|
extensions: []
|
54
61
|
|
55
62
|
extra_rdoc_files:
|
@@ -57,6 +64,7 @@ extra_rdoc_files:
|
|
57
64
|
- README.md
|
58
65
|
files:
|
59
66
|
- bin/fig
|
67
|
+
- bin/fig-download
|
60
68
|
- lib/fig.rb
|
61
69
|
- lib/fig/environment.rb
|
62
70
|
- lib/fig/grammar.treetop
|
@@ -94,7 +102,7 @@ rubyforge_project:
|
|
94
102
|
rubygems_version: 1.3.5
|
95
103
|
signing_key:
|
96
104
|
specification_version: 3
|
97
|
-
summary: Fig is a utility for
|
105
|
+
summary: Fig is a utility for configuring environments and managing dependencies across a team of developers..
|
98
106
|
test_files:
|
99
107
|
- spec/fig_spec.rb
|
100
108
|
- spec/spec_helper.rb
|