Permalink
Browse files

initial commit

  • Loading branch information...
0 parents commit 9ca9b122cf7fce1ca46d271da468ae4fa49f9d67 @mfoemmel committed Dec 30, 2009
Showing with 1,200 additions and 0 deletions.
  1. +5 −0 .document
  2. +23 −0 .gitignore
  3. +27 −0 LICENSE
  4. +66 −0 README.md
  5. +51 −0 Rakefile
  6. +1 −0 VERSION
  7. +129 −0 bin/fig
  8. 0 lib/fig.rb
  9. +137 −0 lib/fig/environment.rb
  10. +149 −0 lib/fig/grammar.treetop
  11. +52 −0 lib/fig/options.rb
  12. +114 −0 lib/fig/os.rb
  13. +195 −0 lib/fig/package.rb
  14. +25 −0 lib/fig/parser.rb
  15. +149 −0 lib/fig/repository.rb
  16. +67 −0 spec/fig_spec.rb
  17. +1 −0 spec/spec.opts
  18. +9 −0 spec/spec_helper.rb
@@ -0,0 +1,5 @@
+README.rdoc
+lib/**/*.rb
+bin/*
+features/**/*.feature
+LICENSE
@@ -0,0 +1,23 @@
+## MAC OS
+.DS_Store
+
+## TEXTMATE
+*.tmproj
+tmtags
+
+## EMACS
+*~
+\#*
+.\#*
+
+## VIM
+*.swp
+
+## PROJECT::GENERAL
+coverage
+rdoc
+pkg
+
+## PROJECT::SPECIFIC
+/fig.gemspec
+/tmp
27 LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2009, Matthew Foemmel
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * The names of the contributors may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,66 @@
+Description
+===========
+
+Fig is a utility for dynamically assembling an environment from a set of packages. Shell commands can then be executed in that package, after which the environment goes away. The caller's environment is never affected.
+
+If fig, an "environment" is just a set of environment variables. A "package" is a collection of files, plus some metadata describing how the environment should be modified when the package is included. For example, a package containing an executable might specify that its "bin" directory be appended to the PATH environment variable. A package containing a Java library might specify that its jar files should be added to the CLASSPATH. Etc.
+
+Packages exist in two places: a "local" repository in the user's home directory, and a "remote" repository that is shared by a team. Fig will automatically download packages from the remote repository and install them in the local repository, when needed. In this sense, fig is a lot like other dependency management tools such as Apache Ivy and Debian APT. Unlike those tools, however, fig is meant to be lightweight, platform agnostic, and language agnostic.
+
+Installation
+============
+
+Fig can be installed via rubygems. The gems are hosted at [Gemcutter](http://gemcutter.org), so you'll need to set that up first:
+
+ $ gem install gemcutter
+ $ gem tumble
+
+Then you can install fig:
+
+ $ gem install fig
+
+Usage
+=====
+
+Fig recognizes the following options:
+
+### Flags ###
+
+ -d, --debug Print debug info
+ --force Download/install packages from remote repository, even if up-to-date
+ -u, --update Download/install packages from remote repository, if out-of-date
+ -n, --no Automatically answer "n" for any prompt (batch mode)
+ -y, --yes Automatically answer "y" for any prompt (batch mode)
+
+
+### Environment Modifiers ###
+
+The following otpions modify the environment generated by fig:
+
+ -i, --include DESCRIPTOR Include package in environment (recursive)
+ -p, --append VAR=VALUE Append value to environment variable using platform-specific separator
+ -s, --set VAR=VALUE Set environment variable
+
+### Environment Commands ###
+
+The following commands will be run in the environment created by fig:
+
+ -b, --bash Print bash commands so user's environment can be updated (usually used with 'eval')
+ -g, --get VARIABLE Get value of environment variable
+ -x, --execute DESCRIPTOR Execute command associated with specified configuration
+
+ -- COMMAND [ARGS...] Execute arbitrary shell command
+
+### Other Commands ###
+
+Fig also supports the following options, which don't require a fig environment. Any modifiers will be ignored:
+
+ -?, -h, --help Display this help text
+ --publish Upload package to the remote repository (also installs in local repository)
+ --publish-local Install package in local repository only
+ --list List the packages installed in local repository
+
+Copyright
+=========
+
+Copyright (c) 2009 Matthew Foemmel. See LICENSE for details.
@@ -0,0 +1,51 @@
+require 'rubygems'
+require 'rake'
+
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |gem|
+ gem.name = "fig"
+ gem.summary = %Q{Fig is a utility for dynamically assembling an environment from a set of packages.}
+ gem.description = %Q{Fig is a utility for dynamically assembling an
+ environment from a set of packages. Shell commands can then be
+ executed in that environment, after which the environment
+ is thrown away. The caller's environment is never affected.}
+ gem.email = "git@foemmel.com"
+ gem.homepage = "http://github.com/mfoemmel/fig"
+ gem.authors = ["Matthew Foemmel"]
+ gem.add_dependency "polyglot", ">= 0.2.9"
+ gem.add_dependency "treetop", ">= 1.4.2"
+ gem.add_development_dependency "rspec", ">= 1.2.9"
+ gem.files = ["bin/fig"] + Dir["lib/**/*.rb"] + Dir["lib/**/*.treetop"]
+ gem.executables = ["fig"]
+ end
+ Jeweler::GemcutterTasks.new
+rescue LoadError
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
+end
+
+require 'spec/rake/spectask'
+Spec::Rake::SpecTask.new(:spec) do |spec|
+ spec.libs << 'lib' << 'spec'
+ spec.spec_files = FileList['spec/**/*_spec.rb']
+end
+
+Spec::Rake::SpecTask.new(:rcov) do |spec|
+ spec.libs << 'lib' << 'spec'
+ spec.pattern = 'spec/**/*_spec.rb'
+ spec.rcov = true
+end
+
+task :spec => :check_dependencies
+
+task :default => :spec
+
+require 'rake/rdoctask'
+Rake::RDocTask.new do |rdoc|
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
+
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = "fig #{version}"
+ rdoc.rdoc_files.include('README*')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
@@ -0,0 +1 @@
+0.1.0
129 bin/fig
@@ -0,0 +1,129 @@
+#!/usr/bin/env ruby
+
+$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
+
+require 'rubygems'
+require 'net/ftp'
+
+require 'fig/options'
+require 'fig/environment'
+require 'fig/repository'
+require 'fig/os'
+require 'fig/parser'
+
+include Fig
+
+def parse_descriptor(descriptor)
+ # todo should use treetop for these:
+ package_name = descriptor =~ /^([^:\/]+)/ ? $1 : nil
+ config_name = descriptor =~ /:([^:\/]+)/ ? $1 : nil
+ version_name = descriptor =~ /\/([^:\/]+)/ ? $1 : nil
+ return package_name, config_name, version_name
+end
+
+ARGV.each_with_index do |arg, i|
+ if arg == "-"
+# $stderr.puts "Use of single dash (-) is deprecated. Use double dash (--) instead"
+# exit 1
+ elsif arg == "--"
+ ARGV[i] = "-"
+ end
+end
+
+options, argv = parse_options(ARGV)
+
+vars = {}
+ENV.each {|key,value| vars[key]=value }
+
+remote_url = nil
+if options[:update] || options[:publish]
+ remote_url = ENV['FIG_REMOTE_URL']
+ if remote_url.nil?
+ $stderr.puts "Please define the FIG_REMOTE_URL environment variable"
+ exit 1
+ end
+end
+
+remote_user = nil
+if options[:publish]
+# remote_user = ENV['FIG_REMOTE_USER']
+# if remote_user.nil?
+# $stderr.puts "Please define the FIG_REMOTE_USER environment variable"
+# exit 1
+# end
+end
+
+os = OS.new
+repos = Repository.new(os, File.expand_path(File.join(options[:home], 'repos')), remote_url, remote_user)
+env = Environment.new(os, repos, vars)
+
+options[:includes].each do |descriptor|
+ package_name, config_name, version_name = parse_descriptor(descriptor)
+ env.include_config(nil, package_name, config_name, version_name)
+end
+
+options[:sets].each do |name_val|
+ env.set_variable(nil, name_val[0], name_val[1])
+end
+
+options[:appends].each do |name_val|
+ env.append_variable(nil, name_val[0], name_val[1])
+end
+
+DEFAULT_FIG_FILE = '.fig'
+
+input = nil
+if options[:input] == '-'
+ input = $stdin.read
+elsif options[:input].nil?
+ input = os.read(DEFAULT_FIG_FILE) if os.exist?(DEFAULT_FIG_FILE)
+else
+ if os.exist?(options[:input])
+ input = os.read(options[:input])
+ else
+ $stderr.puts "File not found: #{options[:input]}"
+ exit 1
+ end
+end
+
+if input
+ package = Parser.new.parse_package(nil, nil, ".", input)
+ if options[:retrieve]
+ package.retrieves.each do |var, path|
+ env.add_retrieve(var, path)
+ end
+ end
+ unless options[:publish] || options[:list]
+ env.register_package(package)
+ env.apply_config(package, options[:config])
+ end
+else
+ package = Package.new(nil, nil, ".", [])
+end
+
+if options[:list]
+ repos.list_packages.sort.each do |item|
+ puts item
+ end
+end
+
+if options[:publish]
+ raise "Unexpected arguments: #{argv.join(' ')}" if !argv.empty?
+ package_name, config_name, version_name = parse_descriptor(options[:publish])
+ if package_name.nil? || version_name.nil?
+ raise "Please specify a package name and a version name"
+ end
+ fail if package.publish_statements.empty?
+ repos.publish_package(package.publish_statements, package_name, version_name)
+elsif options[:echo]
+ puts env[options[:echo]]
+elsif argv[0] == "-"
+ argv.shift
+ env.execute_shell(argv) { |cmd| exec cmd.join(' ') }
+elsif argv[0]
+ package_name, config_name, version_name = parse_descriptor(argv.shift)
+ env.include_config(package, package_name, config_name, version_name)
+ env.execute_config(package, package_name, config_name, nil) { |cmd| exec((cmd + argv).join(' ')) }
+else
+ env.execute_config(package, nil, options[:config], nil) { |cmd| exec((cmd + argv).join(' ')) }
+end
No changes.
Oops, something went wrong.

0 comments on commit 9ca9b12

Please sign in to comment.