fig 0.1.38-java

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2009, Matthew Foemmel
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ * The names of the contributors may not be used to endorse or promote
15
+ products derived from this software without specific prior written
16
+ permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
22
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,229 @@
1
+ Description
2
+ ===========
3
+
4
+ Fig is a utility for configuring environments and managing dependencies across a team of developers. Fig takes a list of packages and a shell command to run, creates an environment that includes those packages, then executes the shell command in that environment. The caller's environment is not affected.
5
+
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
+
8
+ Developers can 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, ensuring 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 shared server. Fig will automatically download packages from the remote repository and install them in the local repository as needed.
11
+
12
+ Fig is similar to a lot of other package/dependency 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 cross platform and project-oriented.
13
+
14
+ Installation
15
+ ============
16
+
17
+ Fig can be installed via rubygems. The gems are hosted at [Gemcutter](http://gemcutter.org), so you'll need to set that up first:
18
+
19
+ $ gem install gemcutter
20
+ $ gem tumble
21
+
22
+ Fig also depends on a third-party library named
23
+ [libarchive](http://libarchive.rubyforge.org/). Libarchive is easily available
24
+ via most package management systems on Linux, FreeBSD, and OS X. Libarchive
25
+ versions greater than 2.6.0 are preferred. If you are on Windows (not Cygwin Ruby), the gem will
26
+ install the libarchive binaries for you.
27
+
28
+ [Linux - Debian / Ubuntu]
29
+ apt-get libarchive-dev
30
+
31
+ [Linux - Red Hat / CentOS]
32
+ yum install libarchive-devel
33
+
34
+ [OS X - MacPorts]
35
+ port install libarchive
36
+
37
+ Then you can install fig:
38
+
39
+ $ gem install fig
40
+
41
+ Usage
42
+ =====
43
+
44
+ Fig recognizes the following options (not all are implemented yet):
45
+
46
+ ### Flags ###
47
+
48
+ -d, --debug Print debug info
49
+ --force Download/install packages from remote repository, even if up-to-date
50
+ -u, --update Download/install packages from remote repository, if out-of-date
51
+ -m, --update-if-missing Download/install packages from remote repository, if not already installed
52
+ -l, --login Authenticate with remote server using username/password (default is anonymous)
53
+
54
+ If the `--login` option is supplied, fig will look for credentials. If
55
+ environment variables `FIG_REMOTE_USER` and/or `FIG_REMOTE_PASSWORD` are
56
+ defined, fig will use them instead of prompting the user. If ~/.netrc exists,
57
+ with an entry corresponding to the host parsed from `FIG_REMOTE_URL`, that
58
+ entry will take precedence over `FIG_REMOTE_USER` and `FIG_REMOTE_PASSWORD`.
59
+ If sufficient credentials are still not found, fig will prompt for whatever is
60
+ still missing, and use the accumulated credentials to authenticate against the
61
+ remote server. Even if both environment variables are defined, fig will only
62
+ use them if `--login` is given.
63
+
64
+ ### Environment Modifiers ###
65
+
66
+ The following otpions modify the environment generated by fig:
67
+
68
+ -i, --include DESCRIPTOR Include package in environment (recursive)
69
+ -p, --append VAR=VALUE Append value to environment variable using platform-specific separator
70
+ -s, --set VAR=VALUE Set environment variable
71
+
72
+ ### Environment Commands ###
73
+
74
+ The following commands will be run in the environment created by fig:
75
+
76
+ -g, --get VARIABLE Get value of environment variable
77
+ -- COMMAND [ARGS...] Execute arbitrary shell command
78
+
79
+ ### Other Commands ###
80
+
81
+ Fig also supports the following options, which don't require a fig environment. Any modifiers will be ignored:
82
+
83
+ -?, -h, --help Display this help text
84
+ --publish Upload package to the remote repository (also installs in local repository)
85
+ --publish-local Install package in local repository only
86
+ --list List packages in local repository
87
+ --list-remote List packages in remote repository
88
+
89
+ When using the `--list-remote` command against an FTP server, fig uses a pool of FTP sessions to improve
90
+ performance. By default it opens 16 connections, but that number can be overridden by setting the
91
+ `FIG_FTP_THREADS` environment variable.
92
+
93
+ Examples
94
+ ========
95
+
96
+ Fig lets you configure environments three different ways:
97
+
98
+ * From the command line
99
+ * From a "package.fig" file in the current directory
100
+ * From packages included indirectly via one of the previous two methods
101
+
102
+ ### Command Line ###
103
+
104
+ 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:
105
+
106
+ $ fig -s GREETING=Hello -- echo "\$GREETING, World"
107
+ Hello, World
108
+
109
+ 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.
110
+
111
+ Also note that when running fig, the original environment isn't affected:
112
+
113
+ $ echo $GREETING
114
+ <nothing>
115
+
116
+ 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:
117
+
118
+ $ mkdir bin
119
+ $ echo "echo \$GREETING, World" > bin/hello
120
+ $ chmod +x bin/hello
121
+ $ fig -s GREETING=Hello -p PATH=bin -- hello
122
+ Hello, World
123
+
124
+ ### Fig Files ###
125
+
126
+ 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:
127
+
128
+ config default
129
+ set GREETING=Hello
130
+ append PATH=@/bin
131
+ end
132
+
133
+ 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:
134
+
135
+ $ fig -- hello
136
+ Hello, World
137
+
138
+ A single fig file can have multiple configurations:
139
+
140
+ config default
141
+ set GREETING=Hello
142
+ append PATH=@/bin
143
+ end
144
+
145
+ config french
146
+ set GREETING=Bonjour
147
+ append PATH=@/bin
148
+ end
149
+
150
+ Configurations other than "default" can be specified using the "-c" option:
151
+
152
+ $ fig -c french -- hello
153
+ Bonjour, World
154
+
155
+ ### Packages ###
156
+
157
+ 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:
158
+
159
+ $ export FIG_REMOTE_URL=ssh://localhost$(pwd)/remote
160
+
161
+ 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:
162
+
163
+ resource bin/hello
164
+
165
+ config default...
166
+
167
+ Now we can share the package with the rest of the team by using the "--publish" option:
168
+
169
+ $ fig --publish hello/1.0.0
170
+
171
+ 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.):
172
+
173
+ $ mv package.fig package.bak
174
+ $ fig -u -i hello/1.0.0 -- hello
175
+ ...downloading files...
176
+ Hello, World
177
+
178
+ 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:
179
+
180
+ $ fig -i hello/1.0.0 -- hello
181
+ Hello, World
182
+
183
+ Also, when including a package, you can specify a particular configuration by appending it to the package name using a colon:
184
+
185
+ $ fig -i hello/1.0.0:french -- hello
186
+ Bonjour, World
187
+
188
+ ### Retrieves ###
189
+
190
+ 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.
191
+
192
+ For example, let's create a package that contains a library for the "foo" programming language. First we'll define a "package.fig" file:
193
+
194
+ config default
195
+ append FOOPATH=lib/hello.foo
196
+ end
197
+
198
+ Then:
199
+
200
+ $ mkdir lib
201
+ $ echo "print 'hello'" > lib/hello.foo
202
+ $ fig --publish hello-lib/3.2.1
203
+
204
+ Now we'll move to a different directory (or delete the current "package.fig" file) and create a new "package.fig" file:
205
+
206
+ retrieve FOOPATH->lib/[package]
207
+ config default
208
+ include hello-lib/3.2.1
209
+ end
210
+
211
+ 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:
212
+
213
+ $ fig -u
214
+ ...downloading...
215
+ ...retrieving...
216
+ $ cat lib/hello-lib/hello.foo
217
+ print 'hello'
218
+
219
+ Community
220
+ =========
221
+
222
+ \#fig on irc.freenode.net
223
+
224
+ [Fig Mailing List](http://groups.google.com/group/fig-user)
225
+
226
+ Copyright
227
+ =========
228
+
229
+ Copyright (c) 2009 Matthew Foemmel. See LICENSE for details.
data/bin/fig ADDED
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
4
+
5
+ require 'rubygems'
6
+ require 'net/ftp'
7
+
8
+ require 'fig/retriever'
9
+ require 'fig/options'
10
+ require 'fig/environment'
11
+ require 'fig/repository'
12
+ require 'fig/os'
13
+ require 'fig/parser'
14
+ require 'fig/windows'
15
+
16
+ include Fig
17
+
18
+ def parse_descriptor(descriptor)
19
+ # todo should use treetop for these:
20
+ package_name = descriptor =~ /^([^:\/]+)/ ? $1 : nil
21
+ config_name = descriptor =~ /:([^:\/]+)/ ? $1 : nil
22
+ version_name = descriptor =~ /\/([^:\/]+)/ ? $1 : nil
23
+ return package_name, config_name, version_name
24
+ end
25
+
26
+ shell_command = nil
27
+ ARGV.each_with_index do |arg, i|
28
+ if arg == "-"
29
+ # $stderr.puts "Use of single dash (-) is deprecated. Use double dash (--) instead"
30
+ # exit 1
31
+ elsif arg == "--"
32
+ shell_command = ARGV[(i+1)..-1]
33
+ ARGV.slice!(i..-1)
34
+ break
35
+ end
36
+ end
37
+
38
+ options, argv = parse_options(ARGV)
39
+
40
+ vars = {}
41
+ ENV.each {|key,value| vars[key]=value }
42
+
43
+ remote_url = nil
44
+ if options[:update] || options[:publish] || options[:update_if_missing] || options[:list_remote]
45
+ remote_url = ENV['FIG_REMOTE_URL']
46
+ if remote_url.nil?
47
+ $stderr.puts "Please define the FIG_REMOTE_URL environment variable"
48
+ exit 1
49
+ end
50
+ end
51
+
52
+ remote_user = nil
53
+ if options[:publish]
54
+ # remote_user = ENV['FIG_REMOTE_USER']
55
+ # if remote_user.nil?
56
+ # $stderr.puts "Please define the FIG_REMOTE_USER environment variable"
57
+ # exit 1
58
+ # end
59
+ end
60
+
61
+ os = OS.new(options[:login])
62
+ repos = Repository.new(os, File.expand_path(File.join(options[:home], 'repos')), remote_url, remote_user, options[:update], options[:update_if_missing])
63
+ retriever = Retriever.new(".")
64
+ at_exit { retriever.save }
65
+ env = Environment.new(os, repos, vars, retriever)
66
+
67
+ options[:modifiers].each do |modifier|
68
+ env.apply_config_statement(nil, modifier, nil)
69
+ end
70
+
71
+ #if File.exist?(".fig")
72
+ # $stderr.puts "The '.fig' file is deprecated. Please rename to 'package.fig'"
73
+ # exit 1
74
+ #end
75
+
76
+ DEFAULT_FIG_FILE = 'package.fig'
77
+
78
+ input = nil
79
+ if options[:input] == :none
80
+ # ignore
81
+ elsif options[:input] == '-'
82
+ input = $stdin.read
83
+ elsif options[:input].nil?
84
+ input = os.read(DEFAULT_FIG_FILE) if os.exist?(DEFAULT_FIG_FILE)
85
+ else
86
+ if os.exist?(options[:input])
87
+ input = os.read(options[:input])
88
+ else
89
+ $stderr.puts "File not found: #{options[:input]}"
90
+ exit 1
91
+ end
92
+ end
93
+
94
+ options[:cleans].each do |descriptor|
95
+ package_name, version_name = descriptor.split('/')
96
+ repos.clean(package_name, version_name)
97
+ end
98
+
99
+ if options[:list]
100
+ repos.list_packages.sort.each do |item|
101
+ puts item
102
+ end
103
+ exit 0
104
+ end
105
+
106
+ if options[:list_remote]
107
+ repos.list_remote_packages.sort.each do |item|
108
+ puts item
109
+ end
110
+ exit 0
111
+ end
112
+
113
+ if not options[:list_configs].empty?
114
+ options[:list_configs].each do |descriptor|
115
+ package_name, version_name = descriptor.split('/')
116
+ repos.read_local_package(package_name, version_name).configs.each do |config|
117
+ puts config.name
118
+ end
119
+ end
120
+ exit 0
121
+ end
122
+
123
+ if input
124
+ package = Parser.new.parse_package(nil, nil, ".", input)
125
+ direct_retrieves=[]
126
+ if options[:retrieve]
127
+ package.retrieves.each do |var, path|
128
+ if var =~ /^@([^\/]+)(.*)/
129
+ direct_retrieves << [$1, $2, path]
130
+ else
131
+ env.add_retrieve(var, path)
132
+ end
133
+ end
134
+ end
135
+ unless options[:publish] || options[:list] || options[:publish_local]
136
+ env.register_package(package)
137
+ env.apply_config(package, options[:config], nil)
138
+ direct_retrieves.each do |info|
139
+ env.direct_retrieve(info[0], info[1], info[2])
140
+ end
141
+ end
142
+ else
143
+ package = Package.new(nil, nil, ".", [])
144
+ end
145
+
146
+ if options[:publish] || options[:publish_local]
147
+ if !argv.empty?
148
+ $stderr.puts "Unexpected arguments: #{argv.join(' ')}"
149
+ exit 10
150
+ end
151
+ package_name, config_name, version_name = parse_descriptor(options[:publish] || options[:publish_local])
152
+ if package_name.nil? || version_name.nil?
153
+ $stderr.puts "Please specify a package name and a version name"
154
+ exit 10
155
+ end
156
+ if not options[:modifiers].empty?
157
+ publish_statements = options[:resources] + options[:archives] + [Configuration.new("default", options[:modifiers])]
158
+ publish_statements << Publish.new("default","default")
159
+ elsif not package.statements.empty?
160
+ publish_statements = package.statements
161
+ else
162
+ $stderr.puts "Nothing to publish"
163
+ exit 1
164
+ end
165
+ if options[:publish]
166
+ puts "Checking status of #{package_name}/#{version_name}..."
167
+ if repos.list_remote_packages.include?("#{package_name}/#{version_name}")
168
+ puts "#{package_name}/#{version_name} has already been published"
169
+ if not options[:force]
170
+ puts "Use the --force option if you really want to overwrite, or us --publish-local for testing"
171
+ exit 1
172
+ else
173
+ puts "Overwriting..."
174
+ end
175
+ end
176
+ end
177
+ puts "Publishing #{package_name}/#{version_name}"
178
+ repos.publish_package(publish_statements, package_name, version_name, options[:publish_local])
179
+ elsif options[:echo]
180
+ puts env[options[:echo]]
181
+ elsif shell_command
182
+ argv.shift
183
+ env.execute_shell(shell_command) { |cmd| os.shell_exec cmd }
184
+ elsif argv[0]
185
+ package_name, config_name, version_name = parse_descriptor(argv.shift)
186
+ env.include_config(package, package_name, config_name, version_name, {}, nil)
187
+ env.execute_config(package, package_name, config_name, nil, argv) { |cmd| os.shell_exec cmd }
188
+ elsif input
189
+ env.execute_config(package, nil, options[:config], nil, argv) { |cmd| os.shell_exec cmd }
190
+ end
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