depends-client 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright [2012] [Business Intelligence Associates, Inc.]
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ Depends
2
+ =======
3
+ Depends is a basic dependency management system _inspired_ by bundler. The basic idea is that you have some
4
+ dependencies that need to be put in place in order to begin developing your application. Our use case is that we have
5
+ a number of libraries such as OpenSSL, xsd, qt, etc... that we want to precompile and link the results at (our)
6
+ application build time. We _don't_ want to check these into source countrol, but we want them to be versioned along-side
7
+ source control.
8
+
9
+ Introducting Depends
10
+ --------------------
11
+ Depends is quite simple.
12
+
13
+ 1. Install depends (I am assuming that ruby is already installed)
14
+
15
+ ```bash
16
+ gem install depends-client
17
+ ```
18
+
19
+ 2. Define a Depends file at the root of your source repository. The format is as follows:
20
+
21
+ ```ruby
22
+
23
+ source :depends
24
+
25
+ depend 'Qt', :version => '4', :destination => 'External/Qt'
26
+ depend 'SevenZipSharp', :version => '4', :destination => 'External/SevenZipSharp'
27
+ depend 'Sqlite', :version => '4', :destination => 'External/Sqlite'
28
+ depend 'Xerces', :version => '4', :destination => 'External/Xerces'
29
+ depend 'Xsd', :version => '4', :destination => 'External/Xsd'
30
+
31
+ ```
32
+
33
+ _source_ defines that location of the depends server. Currently :local, :depends, or a string to some other depends
34
+ server, i.e. http://example.com.
35
+
36
+ _depend_ defines what the dependency is, the version to install and the path to unpack it to
37
+
38
+ 3. Execute Depends
39
+ ```bash
40
+ depend
41
+ ```
42
+
43
+ 4. Add your Depends file to source control
44
+
45
+ _We also recomend that you add depends destinations to your gitignore and hgignore files._
46
+
47
+ Your done, packages are download, extracted and installed per the instructions in your gem file
48
+
49
+
50
+ Uploading A Dependency
51
+ ----------------------
52
+ This tutorial does not cover installing a depends server, but asuming that you have a depends server setup, adding a new
53
+ dependency is simple.
54
+
55
+ 1. Install Depends
56
+
57
+ ```bash
58
+ gem install depends
59
+ ````
60
+ 2. Setup a directory that models what you want to upload. I.e. Create /tmp/openssl and add some files to it.
61
+ 3. Package and upload
62
+
63
+ ```bash
64
+ depend upload -s /tmp/openssl -d 'depends' -n "OpenSSL" -v '1.2.3b'
65
+ ```
66
+
67
+ That's it, your package is created and uploaded to the depends server.
68
+
69
+ The Future
70
+ ==========
71
+ * Polish the client a bit further
72
+ * Better error handling
73
+ * Auto Updating of .gitignore and .hgignore files based on your Depends
74
+ * Windows support
75
+ * Rake tasks
data/bin/depend ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'depends'
4
+ time = Benchmark.realtime do
5
+ begin
6
+ a = Depends::CommandFactory.build.new
7
+ a.run
8
+ rescue Depends::Exceptions::SubCommandMissing => e
9
+ Depends::Log.debug ("Exception: #{e.inspect}")
10
+ Depends::Log.fatal ("SubCommand is not defined #{e.message}")
11
+ Process.exit 1
12
+ end
13
+ end
14
+
15
+ Depends::Log.debug ":total_runtime => #{time*1000} milliseconds"
16
+
17
+
@@ -0,0 +1,31 @@
1
+ module Depends
2
+ module CommandFactory
3
+ class << self
4
+ def build
5
+ subcommand_class
6
+ end
7
+
8
+ private
9
+ def subcommand_class
10
+ command_words = ARGV.select {|arg| arg =~ /^(([[:alnum:]])[[:alnum:]\_\-]+)$/ }
11
+ if command_words.empty?
12
+ return Depends::Commands::Install
13
+ end
14
+ command_words.collect! {|word| word.titleize }
15
+ command_options = []
16
+ subcommand_class = nil
17
+
18
+ while ( !subcommand_class ) && ( !command_words.empty? )
19
+ constant_case_name = command_words.join('')
20
+ command_options << constant_case_name
21
+ command_constant = Depends::Commands.constants.select { |i| i.eql? constant_case_name.to_sym}
22
+ unless command_constant.empty?
23
+ return "Depends::Commands::#{constant_case_name}".constantize
24
+ end
25
+ command_words.pop
26
+ end
27
+ raise Depends::Exceptions::SubCommandMissing, "Possible SubCommands: #{command_options} "
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,87 @@
1
+ module Depends
2
+ module Commands
3
+ class Base
4
+
5
+ include Mixlib::CLI
6
+
7
+ def initialize
8
+ super
9
+
10
+ trap("TERM") do
11
+ Depends::Commands::Base.fatal!("SIGTERM received, stopping", 1)
12
+ end
13
+
14
+ trap("INT") do
15
+ Depends::Commands::Base.fatal!("SIGINT received, stopping", 2)
16
+ end
17
+
18
+ processor, platform, *rest = RUBY_PLATFORM.split("-")
19
+
20
+ unless platform == 'mswin32'
21
+ trap("QUIT") do
22
+ Depends::Log.info("SIGQUIT received, call stack:\n " + caller.join("\n "))
23
+ end
24
+
25
+ trap("HUP") do
26
+ Depends::Log.info("SIGHUP received, reconfiguring")
27
+ reconfigure
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ def reconfigure
34
+ parse_options
35
+ configure_depends
36
+ configure_logging
37
+ end
38
+
39
+ def run
40
+ reconfigure
41
+ setup_application
42
+ run_application
43
+ end
44
+
45
+
46
+ private
47
+ def configure_depends
48
+
49
+ if File.exist?('~/.depends')
50
+ Depends::Log.info "Loading config file from '~/.depends'"
51
+ Depends::Config.from_file('~/.depends')
52
+ end
53
+
54
+ FileUtils.mkdir_p Depends::Config.cache
55
+ end
56
+
57
+ def configure_logging
58
+ Depends::Log.formatter = Depends::Log::Formatter.new
59
+ Depends::Log.level = config[:log_level] || Logger::INFO
60
+ end
61
+
62
+ # Called prior to starting the application, by the run method
63
+ def setup_application
64
+ raise Depends::Exceptions::Application, "#{self.to_s}: you must override setup_application"
65
+ end
66
+
67
+ # Actually run the application
68
+ def run_application
69
+ raise Depends::Exceptions::Application, "#{self.to_s}: you must override run_application"
70
+ end
71
+
72
+ class << self
73
+
74
+ # Log a fatal error message to both STDERR and the Logger, exit the application
75
+ def fatal!(msg, err = -1)
76
+ Depends::Log.fatal(msg)
77
+ Process.exit err
78
+ end
79
+
80
+ def exit!(msg, err = -1)
81
+ Depends::Log.debug(msg)
82
+ Process.exit err
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,93 @@
1
+ require 'benchmark'
2
+ module Depends
3
+ module Commands
4
+ class Install < Depends::Commands::Base
5
+
6
+ banner "Install dependencies"
7
+
8
+ option :log_level,
9
+ :short => "-l LEVEL",
10
+ :long => "--log_level LEVEL",
11
+ :description => "Set the log level (debug, info, warn, error, fatal)",
12
+ :proc => Proc.new { |l| l.downcase.to_sym }
13
+
14
+ def setup_application
15
+ Log.info "Installing dependencies..."
16
+ end
17
+
18
+ def run_application
19
+
20
+ time = Benchmark.realtime do
21
+ check_for_file
22
+ end
23
+ Depends::Log.debug ":check_for_file => #{time*1000} milliseconds"
24
+
25
+ time = Benchmark.realtime do
26
+ load_depends_file
27
+ end
28
+ Depends::Log.debug ":load_depends_file => #{time*1000} milliseconds"
29
+
30
+ time = Benchmark.realtime do
31
+ download_extract
32
+ end
33
+ Depends::Log.debug ":download_extract => #{time*1000} milliseconds"
34
+
35
+ time = Benchmark.realtime do
36
+ link
37
+ end
38
+ Depends::Log.debug ":link => #{time*1000} milliseconds"
39
+
40
+ end
41
+
42
+ private
43
+ def check_for_file
44
+ unless Dir.entries(Dir.pwd).include?('Depends')
45
+ Depends::Log.error "Missing Depends file"
46
+ exit 1
47
+ end
48
+ end
49
+
50
+ def load_depends_file
51
+ Depends::Log.info "Loading Dependencies..."
52
+ @def = Depends::DSL::Depend.evaluate('Depends')
53
+ unless @def.unmet_dependencies.empty?
54
+ Depends::Log.fatal "You have unmet dependencies in your sources, #{@def.unmet_dependencies.inspect}"
55
+ Process.exit 1
56
+ end
57
+ end
58
+
59
+
60
+ def download_extract
61
+ Depends::Log.info "Downloading and extracting missing dependencies..."
62
+ @def.dependencies.each do |dep|
63
+ cache_file = File.join(Depends::Config.cache,File.basename(dep["file"]))
64
+ cache_directory = File.join(Depends::Config.cache,File.basename(dep["file"],'.zip'))
65
+
66
+ unless File.exist?(cache_file) # and Digest::SHA1.file(cache_file).to_s.eql? dep["sha1"]
67
+ Depends::Log.info "Downloading #{dep[:name]}..."
68
+ just_downloaded = true
69
+ dep[:source].download_depend_version(dep[:name],dep["number"])
70
+ end
71
+
72
+ if just_downloaded or not File.exist? cache_directory
73
+ Depends::Log.info "Extracting #{cache_file}"
74
+ Util.un_zip(cache_file,cache_directory) unless config[:dry_run]
75
+ end
76
+
77
+ end
78
+ end
79
+
80
+ def link
81
+ @def.dependencies.each do |dep|
82
+ source = File.join(Depends::Config.cache,File.basename(dep["file"],'.zip'))
83
+ base_dir = File.dirname(dep[:destination])
84
+ FileUtils.mkdir_p(base_dir) unless File.exist? base_dir
85
+ FileUtils.rm(dep[:destination]) if File.directory? dep[:destination]
86
+ Depends::Log.info "Linking #{source} to #{dep[:destination]}"
87
+ FileUtils.symlink(source, dep[:destination])
88
+ end
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,85 @@
1
+ module Depends
2
+ module Commands
3
+ class Upload < Depends::Commands::Base
4
+
5
+ class UploadConfig
6
+ extend(Mixlib::Config)
7
+ end
8
+
9
+ banner "Upload a dependency to a depends server"
10
+
11
+ option :source,
12
+ :short => "-s source",
13
+ :long => "--source source",
14
+ :description => "Source directory for dependency",
15
+ :required => true
16
+
17
+ option :name,
18
+ :short => "-n name",
19
+ :long => "--name name",
20
+ :description => "Dependency Name",
21
+ :required => true
22
+
23
+ option :version,
24
+ :short => "-v version",
25
+ :long => "--version version",
26
+ :description => "Version to publish",
27
+ :required => true
28
+
29
+ option :destination,
30
+ :short => "-d destination",
31
+ :long => "--destination destination",
32
+ :description => "Destination to publish depend to",
33
+ :default => 'https://depends.io',
34
+ :proc => Proc.new { |o|
35
+ Depends::Util.depends_source o
36
+ }
37
+
38
+ option :log_level,
39
+ :short => "-l LEVEL",
40
+ :long => "--log_level LEVEL",
41
+ :description => "Set the log level (debug, info, warn, error, fatal)",
42
+ :proc => Proc.new { |l| l.downcase.to_sym }
43
+
44
+ def setup_application
45
+
46
+ end
47
+
48
+ def run_application
49
+ client = Depends::RestClient.new(config[:destination])
50
+
51
+ begin
52
+ @dep = client.get_depend(config[:name])
53
+ rescue Nestful::ResourceNotFound => e
54
+ @dep = client.create_depend(config[:name])
55
+ end
56
+
57
+ file = build_package
58
+ sha1 = Digest::SHA1.file(file).to_s
59
+
60
+ if @dep['versions'].select { |v| v.eql? config[:version] }.empty?
61
+ client.create_version(@dep['name'], :file => file, :sha1 => sha1, :version => config[:version])
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ def build_package
68
+ upload_dir = File.join(Depends::Config.cache,'upload')
69
+ FileUtils.mkdir_p upload_dir unless File.exist? upload_dir
70
+ dest_file = File.join(upload_dir, "#{config[:name]}-#{config[:version]}.zip")
71
+ FileUtils.rm dest_file if File.exist? dest_file
72
+ source_path = File.expand_path(config[:source])
73
+ Zip::ZipFile.open(dest_file, Zip::ZipFile::CREATE) { |zipfile|
74
+ Dir["#{source_path}/**/*"].each do |file|
75
+ relative_path = file.to_s.gsub(source_path, '')
76
+ relative_path.gsub! /^\//,''
77
+
78
+ zipfile.add relative_path, file
79
+ end
80
+ }
81
+ dest_file
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,7 @@
1
+ module Depends
2
+ class Config
3
+ extend(Mixlib::Config)
4
+
5
+ cache File.expand_path('~/.depends_cache')
6
+ end
7
+ end
@@ -0,0 +1,45 @@
1
+ module Depends
2
+
3
+ class Definition
4
+
5
+ attr_reader :sources
6
+ attr_reader :dependencies
7
+ attr_reader :unmet_dependencies
8
+
9
+ def initialize(sources,dependencies, options ={})
10
+ @sources = sources
11
+ map(dependencies)
12
+ end
13
+
14
+ def map(deps)
15
+ @dependencies = []
16
+ @unmet_dependencies = []
17
+ Log.debug " :definition => #{@def.inspect}"
18
+ deps.each do |dep|
19
+ dependency_met = false
20
+ sources.each do |source|
21
+ begin
22
+ server_dep = source.get_dep_version(dep[:name], dep[:version] )
23
+ server_dep[:source] = source
24
+ server_dep[:destination] = dep[:destination]
25
+ server_dep[:name] = dep[:name]
26
+ Log.debug ":server_dep => #{server_dep}"
27
+ @dependencies << server_dep
28
+ dependency_met = true
29
+ rescue Nestful::ResourceNotFound => e
30
+ Log.debug ":resource_not_found => #{e.inspect}"
31
+ end
32
+ end
33
+
34
+ @unmet_dependencies << dep unless dependency_met
35
+ end
36
+
37
+
38
+ end
39
+
40
+ def inspect
41
+ "#{self} sources=> #{sources} dependencies => #{dependencies}"
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,52 @@
1
+ module Depends
2
+ module DSL
3
+ class Depend
4
+ def self.evaluate(dependsfile)
5
+ depends = new
6
+ unless File.exist? dependsfile.to_s
7
+ raise IOError, "Depends files does not exist #{dependsfile}"
8
+ end
9
+
10
+ depends.instance_eval(File.read(dependsfile.to_s), dependsfile.to_s, 1)
11
+
12
+ depends.to_definition
13
+ end
14
+
15
+ def initialize
16
+ @sources = []
17
+ @dependencies = []
18
+ end
19
+
20
+ def depend(name,options = {})
21
+ version = options[:version] || :latest
22
+ unless options[:destination]
23
+ raise Exceptions::DslError, "Destination is a required attribute"
24
+ end
25
+
26
+ destination = options[:destination]
27
+
28
+
29
+ @dependencies.push(
30
+ HashWithIndifferentAccess.new ({ :name => name.downcase,
31
+ :version => version,
32
+ :destination => destination }))
33
+ end
34
+
35
+ def source(source, options = {})
36
+ depends_source Depends::Util.depends_source(source)
37
+ end
38
+
39
+ def to_definition
40
+ @sources.uniq!
41
+ raise DslError, "No source specified! Try source :bigdepends" unless @sources.length > 0
42
+ Depends::Definition.new(@sources, @dependencies)
43
+ end
44
+
45
+ private
46
+ def depends_source(source)
47
+ @sources << Depends::RestClient.new(source)
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,8 @@
1
+ module Depends
2
+ module Exceptions
3
+ class DslError < StandardError; end
4
+ class Application < StandardError; end
5
+ class SubCommandMissing < StandardError; end
6
+ class DependencyNotMet < StandardError; end
7
+ end
8
+ end
@@ -0,0 +1,41 @@
1
+ require 'logger'
2
+ require 'time'
3
+
4
+ module Depends
5
+ class Log
6
+ class Formatter < Logger::Formatter
7
+ @@show_time = false
8
+
9
+ COLOR_MAP = {'DEBUG' =>'0;37', 'INFO'=>'32', 'WARN'=>'33', 'ERROR'=>'31', 'FATAL'=>'31', 'UNKNOWN'=>'37'}
10
+
11
+ def self.show_time=(show=false)
12
+ @@show_time = show
13
+ end
14
+
15
+ def call(severity, time, progname, msg)
16
+ color = COLOR_MAP[severity]
17
+
18
+ if @@show_time
19
+ sprintf("\033[0;37m%s \033[0m[\033[#{color}m%s\033[0m]: \033[0m%s\n", time.rfc2822(), severity, msg2str(msg))
20
+ else
21
+ sprintf("\033[#{color}m%s\033[0;37m: \033[0m%s\n", severity, msg2str(msg))
22
+ end
23
+ end
24
+
25
+ # Converts some argument to a Logger.severity() call to a string. Regular strings pass through like
26
+ # normal, Exceptions get formatted as "message (class)\nbacktrace", and other random stuff gets
27
+ # put through "object.inspect"
28
+ def msg2str(msg)
29
+ case msg
30
+ when ::String
31
+ msg
32
+ when ::Exception
33
+ "#{ msg.message } (#{ msg.class })\n" <<
34
+ (msg.backtrace || []).join("\n")
35
+ else
36
+ msg.inspect
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,6 @@
1
+ module Depends
2
+ class Log
3
+ extend Mixlib::Log
4
+ end
5
+ end
6
+
@@ -0,0 +1,73 @@
1
+ require 'nestful'
2
+ module Depends
3
+ class RestClient
4
+
5
+ attr_accessor :source_url
6
+ attr_reader :cache
7
+
8
+ def initialize(source)
9
+ @source_url = source
10
+ cache_path = File.join(Depends::Config.cache,'rest',URI.parse(source).hostname )
11
+ Depends::Log.debug ":cache_path => #{cache_path}"
12
+ @cache = ActiveSupport::Cache::FileStore.new(cache_path, :expires_in => 1.day)
13
+ end
14
+
15
+ def create_version(name,options = {})
16
+ Nestful.post "#{source_url}/dependency/#{name}/versions", :format => :multipart, :timeout => 3600, :params => {:version => options[:version] , :file => File.open(options[:file]), :sha1 => options[:sha1] }
17
+ end
18
+
19
+ def create_depend(name)
20
+ Nestful.post "#{source_url}/dependency", :format => :json, :params => {:name => name}
21
+ end
22
+
23
+ def get_depend(name)
24
+ uri = "#{source_url}/dependency/#{name}"
25
+ depend = cache.read(uri)
26
+ if depend.nil?
27
+ depend = Nestful.get uri, :format => :json
28
+ cache.write(uri,depend.to_json)
29
+ else
30
+ depend = ::MultiJson.load(depend)
31
+ end
32
+ depend
33
+ end
34
+
35
+ def download_depend_version(name,version)
36
+ dest_file = File.join(Depends::Config.cache, "#{name}-#{version}.zip")
37
+ file_buffer = Nestful.get "#{source_url}/dependency/#{name}/versions/#{version}/download" , :allow_redirect => true, :buffer => true
38
+ FileUtils.move file_buffer, dest_file
39
+ dest_file
40
+ end
41
+
42
+ def list(options = {})
43
+ params = {}
44
+
45
+ if params[:depends_list]
46
+ Nestful.post "#{source_url}/dependency/search", :params => params, :format => :json
47
+ else
48
+ Nestful.get "#{source_url}/dependency", :format => :json
49
+ end
50
+
51
+ end
52
+
53
+ def get_latest_version(name)
54
+ JSON.parse( Nestful.get "#{source_url}/dependency/#{name}/versions/latest" )
55
+ end
56
+
57
+
58
+ def get_dep_version(name,version)
59
+ Depends::Log.debug "[get] :ver => #{version}"
60
+ uri = "#{source_url}/dependency/#{name}/versions/#{version}"
61
+ depend = cache.read(uri)
62
+ if depend.nil?
63
+ depend = Nestful.get uri, :format => :json
64
+ cache.write(uri,depend.to_json)
65
+ else
66
+ depend = ::MultiJson.load(depend)
67
+ end
68
+ depend
69
+ end
70
+
71
+
72
+ end
73
+ end
@@ -0,0 +1,36 @@
1
+ require 'zip/zip'
2
+
3
+ module Depends
4
+ module Util
5
+
6
+ def self.un_zip(source,destination, options = {})
7
+ options.reverse_merge!({:overwrite => true})
8
+ Log.debug "Opening #{source}"
9
+ Zip::ZipFile.open(source) do |zip|
10
+ zip.each do |entry|
11
+ Log.debug (":entry => #{entry.name}")
12
+ path = ::File.join(destination, entry.name)
13
+ FileUtils.mkdir_p(::File.dirname(path))
14
+ if options[:overwrite] && ::File.exists?(path) && !::File.directory?(path)
15
+ Log.debug("Removing #{path}")
16
+ FileUtils.rm(path)
17
+ end
18
+ zip.extract(entry, path)
19
+ end
20
+ end
21
+
22
+ end
23
+
24
+ def self.depends_source(source)
25
+ source = source.downcase.to_sym if source.is_a? String
26
+ case source
27
+ when :local
28
+ "http://localhost:8080"
29
+ when :depends
30
+ "http://depends.io"
31
+ else
32
+ source
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/depends.rb ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'fileutils'
6
+ require 'logger'
7
+ require 'mixlib/log'
8
+ require 'mixlib/config'
9
+ require 'mixlib/cli'
10
+ require 'digest/sha1'
11
+ require 'multi_json'
12
+
13
+
14
+ require 'depends/exceptions'
15
+ require 'depends/config'
16
+ require 'depends/util'
17
+ require 'depends/rest_client'
18
+ require 'depends/dsl/depend'
19
+ require 'depends/definition'
20
+ require 'depends/log/formatter'
21
+ require 'depends/log'
22
+ require 'depends/command_factory'
23
+
24
+ require 'depends/commands/base'
25
+ require 'depends/commands/install'
26
+ require 'depends/commands/upload'
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: depends-client
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris Roby
9
+ - Paul Morton
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-04-21 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: mixlib-log
17
+ requirement: &70141195519980 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 1.3.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70141195519980
26
+ - !ruby/object:Gem::Dependency
27
+ name: nestful
28
+ requirement: &70141195519180 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.8
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: *70141195519180
37
+ - !ruby/object:Gem::Dependency
38
+ name: mixlib-config
39
+ requirement: &70141195516600 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 1.1.2
45
+ type: :runtime
46
+ prerelease: false
47
+ version_requirements: *70141195516600
48
+ - !ruby/object:Gem::Dependency
49
+ name: rubyzip
50
+ requirement: &70141195516060 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 0.9.7
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *70141195516060
59
+ - !ruby/object:Gem::Dependency
60
+ name: mixlib-cli
61
+ requirement: &70141195515520 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 1.2.2
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *70141195515520
70
+ - !ruby/object:Gem::Dependency
71
+ name: activesupport
72
+ requirement: &70141195543660 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 3.2.3
78
+ type: :runtime
79
+ prerelease: false
80
+ version_requirements: *70141195543660
81
+ - !ruby/object:Gem::Dependency
82
+ name: rack-cache
83
+ requirement: &70141195541840 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ~>
87
+ - !ruby/object:Gem::Version
88
+ version: '1.2'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: *70141195541840
92
+ - !ruby/object:Gem::Dependency
93
+ name: multi_json
94
+ requirement: &70141195539300 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: 1.3.2
100
+ type: :runtime
101
+ prerelease: false
102
+ version_requirements: *70141195539300
103
+ description:
104
+ email:
105
+ - croby@biaprotect.com
106
+ - pmorton@biaprotect.com
107
+ executables:
108
+ - depend
109
+ extensions: []
110
+ extra_rdoc_files: []
111
+ files:
112
+ - bin/depend
113
+ - lib/depends/command_factory.rb
114
+ - lib/depends/commands/base.rb
115
+ - lib/depends/commands/install.rb
116
+ - lib/depends/commands/upload.rb
117
+ - lib/depends/config.rb
118
+ - lib/depends/definition.rb
119
+ - lib/depends/dsl/depend.rb
120
+ - lib/depends/exceptions.rb
121
+ - lib/depends/log/formatter.rb
122
+ - lib/depends/log.rb
123
+ - lib/depends/rest_client.rb
124
+ - lib/depends/util.rb
125
+ - lib/depends.rb
126
+ - LICENSE
127
+ - README.md
128
+ homepage: http://github.com/BIAINC/depends
129
+ licenses: []
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 1.8.15
149
+ signing_key:
150
+ specification_version: 3
151
+ summary: A simple dependency manager
152
+ test_files: []