gip 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 François Beausoleil
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,22 @@
1
+ = Gip into place: Piston without the SVN cruft
2
+
3
+ This is an implementation of Tom Dysinger's http://dysinger.net/2008/04/29/replacing-braid-or-piston-for-git-with-40-lines-of-rake/ as a full command-line client. I'm standing on the shoulders of giants...
4
+
5
+ Gip is a thin layer above git-read-tree. If you want more information, you can look at http://assets.en.oreilly.com/1/event/24/Smacking%20Git%20Around%20-%20Advanced%20Git%20Tricks%20Presentation.pdf, pages 254-297.
6
+
7
+ == Fair Warning
8
+
9
+ Since Gip copies the upstream repositories directly in your repository, please be advised that your repository will *grow* quickly. For each remote you add, you will receive all commits from that repository. That also means the full history for that project. And when I mean all, I do mean it. If you vendor Rails, you are forewarned: you will add nearly 20 MiB to your own repository. This is a trade-off between Piston (which only imports the latest HEAD) and having subtrees available for easily propagating changes upstream.
10
+
11
+ == Usage
12
+
13
+ $ gip import git://github.com/mislav/will_paginate.git vendor/plugins/mislav-will_paginate
14
+ $ gip update vendor/plugins/mislav-will_paginate
15
+
16
+ Gip stores it's metadata in a .gipinfo file.
17
+
18
+ Gip automatically commits whenever possible: after import, after update. If after an update a conflict occurs, the commit will be aborted and you are given the chance to resolve the conflicts. You have the full power of Git at your disposal.
19
+
20
+ == Copyright
21
+
22
+ Copyright (c) 2009 François Beausoleil. See LICENSE for details.
@@ -0,0 +1,71 @@
1
+ # coding: utf-8
2
+ require 'rubygems'
3
+ require 'rake'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "gip"
9
+ gem.summary = %Q{Gip into place: Piston without the SVN cruft}
10
+ gem.email = "francois@teksol.info"
11
+ gem.homepage = "http://github.com/francois/gip"
12
+ gem.authors = ["François Beausoleil"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+
15
+ gem.add_dependency "thor", "~> 0.11.0"
16
+
17
+ gem.add_development_dependency "cucumber"
18
+ gem.add_development_dependency "jeweler"
19
+ gem.add_development_dependency "ruby-debug19"
20
+ end
21
+
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
24
+ end
25
+
26
+ require 'rake/testtask'
27
+ Rake::TestTask.new(:test) do |test|
28
+ test.libs << 'lib' << 'test'
29
+ test.pattern = 'test/**/*_test.rb'
30
+ test.verbose = true
31
+ end
32
+
33
+ begin
34
+ require 'rcov/rcovtask'
35
+ Rcov::RcovTask.new do |test|
36
+ test.libs << 'test'
37
+ test.pattern = 'test/**/*_test.rb'
38
+ test.verbose = true
39
+ end
40
+ rescue LoadError
41
+ task :rcov do
42
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
43
+ end
44
+ end
45
+
46
+ begin
47
+ require 'cucumber/rake/task'
48
+ Cucumber::Rake::Task.new(:features)
49
+ rescue LoadError
50
+ task :features do
51
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
52
+ end
53
+ end
54
+
55
+ task :default => :test
56
+
57
+ require 'rdoc/task'
58
+ Rake::RDocTask.new do |rdoc|
59
+ if File.exist?('VERSION.yml')
60
+ config = YAML.load(File.read('VERSION.yml'))
61
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
62
+ else
63
+ version = ""
64
+ end
65
+
66
+ rdoc.rdoc_dir = 'rdoc'
67
+ rdoc.title = "gip #{version}"
68
+ rdoc.rdoc_files.include('README*')
69
+ rdoc.rdoc_files.include('lib/**/*.rb')
70
+ end
71
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
data/bin/gip ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require "gip"
3
+ Gip.start
@@ -0,0 +1,12 @@
1
+ Feature: Importing a repository
2
+ In order to have control over his deployments
3
+ A developer will import a remote repository
4
+ So that his vendor code is protected from inadvertent upstream changes
5
+
6
+ Scenario: Importing into an existing repository
7
+ Given a project
8
+ And a vendor project named "libcalc"
9
+ When I run "gip import __libcalc__ vendor/libcalc"
10
+ Then I should see "Imported __libcalc__ into vendor/libcalc"
11
+ And the file ".gipinfo" should contain "vendor/libcalc,__libcalc__"
12
+ And the working copy should be clean
@@ -0,0 +1,42 @@
1
+ Given /^a project$/ do
2
+ Dir.chdir(project_dir) do
3
+ sh "cd #{project_dir}"
4
+ sh "touch README"
5
+ sh "git init"
6
+ sh "git add --all"
7
+ sh "git commit --message 'Initial commit'"
8
+ sh "ls -A"
9
+ end
10
+ end
11
+
12
+ Given /^a vendor project named "([^"]+)"$/ do |name|
13
+ vendor(name) do |path|
14
+ sh "cd #{path}"
15
+ sh "touch README"
16
+ sh "mkdir lib"
17
+ sh "touch lib/#{name}.rb"
18
+ sh "git init", :verbose => true
19
+ sh "git add --all", :verbose => true
20
+ sh "git commit --message 'Initial commit'", :verbose => true
21
+ sh "ls -lA", :verbose => true
22
+ end
23
+ end
24
+
25
+ When /^I run "gip import __([^_]+)__ ([^"]+)"$/ do |vendor, target|
26
+ Dir.chdir(project_dir) do
27
+ sh "gip import #{vendor_dirs[vendor]}/.git #{target}", :verbose => true
28
+ end
29
+ pending
30
+ end
31
+
32
+ Then /^I should see "([^\"]*)"$/ do |arg1|
33
+ pending
34
+ end
35
+
36
+ Then /^the file '\.gipinfo' should contain 'vendor\/libcalc,__libcalc__'$/ do
37
+ pending
38
+ end
39
+
40
+ Then /^the working copy should be clean$/ do
41
+ pending
42
+ end
@@ -0,0 +1,11 @@
1
+ def sh(command_line, options={})
2
+ verbose = $DEBUG || options[:verbose]
3
+ puts "CWD:#{Dir.pwd}" if verbose
4
+ p command_line if verbose
5
+ result = `#{command_line}`
6
+ p $? if verbose
7
+ puts "====" if verbose
8
+ puts result if verbose
9
+ puts "====" if verbose
10
+ result
11
+ end
@@ -0,0 +1,35 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require "gip"
3
+ require "pathname"
4
+ require "fileutils"
5
+
6
+ require "test/unit/assertions"
7
+
8
+ module GipHelpers
9
+ def project_dir
10
+ @project_dir ||= begin
11
+ path = Pathname.new(Dir.tmpdir) + "gip/#{Process.pid}/project-dir"
12
+ path.mkpath
13
+ path
14
+ end
15
+ end
16
+
17
+ def reset_vendors!
18
+ @vendor_dirs ||= Hash.new
19
+ @vendor_dirs.values.each {|dir| dir.rmtree }
20
+ @vendor_dirs.clear
21
+ end
22
+
23
+ attr_reader :vendor_dirs
24
+
25
+ def vendor(basename)
26
+ Pathname.new(Dir.tmpdir) + "gip/#{Process.pid}/#{basename}"
27
+ end
28
+ end
29
+
30
+ World(GipHelpers)
31
+ World(Test::Unit::Assertions)
32
+
33
+ Before do
34
+ reset_vendors!
35
+ end
@@ -0,0 +1,86 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{gip}
8
+ s.version = "0.3.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{François Beausoleil}]
12
+ s.date = %q{2011-11-01}
13
+ s.email = %q{francois@teksol.info}
14
+ s.executables = [%q{gip}]
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "bin/gip",
27
+ "features/import.feature",
28
+ "features/step_definitions/gip_steps.rb",
29
+ "features/support/command_line.rb",
30
+ "features/support/env.rb",
31
+ "gip.gemspec",
32
+ "lib/gip.rb",
33
+ "test/gip_test.rb",
34
+ "test/test_helper.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/francois/gip}
37
+ s.require_paths = [%q{lib}]
38
+ s.rubygems_version = %q{1.8.6}
39
+ s.summary = %q{Gip into place: Piston without the SVN cruft}
40
+
41
+ if s.respond_to? :specification_version then
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_runtime_dependency(%q<gip>, [">= 0"])
46
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
47
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
48
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
49
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
50
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
51
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
52
+ s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
53
+ s.add_runtime_dependency(%q<thor>, ["~> 0.11.0"])
54
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
55
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
56
+ s.add_development_dependency(%q<ruby-debug19>, [">= 0"])
57
+ else
58
+ s.add_dependency(%q<gip>, [">= 0"])
59
+ s.add_dependency(%q<cucumber>, [">= 0"])
60
+ s.add_dependency(%q<jeweler>, [">= 0"])
61
+ s.add_dependency(%q<cucumber>, [">= 0"])
62
+ s.add_dependency(%q<jeweler>, [">= 0"])
63
+ s.add_dependency(%q<cucumber>, [">= 0"])
64
+ s.add_dependency(%q<jeweler>, [">= 0"])
65
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
66
+ s.add_dependency(%q<thor>, ["~> 0.11.0"])
67
+ s.add_dependency(%q<cucumber>, [">= 0"])
68
+ s.add_dependency(%q<jeweler>, [">= 0"])
69
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
70
+ end
71
+ else
72
+ s.add_dependency(%q<gip>, [">= 0"])
73
+ s.add_dependency(%q<cucumber>, [">= 0"])
74
+ s.add_dependency(%q<jeweler>, [">= 0"])
75
+ s.add_dependency(%q<cucumber>, [">= 0"])
76
+ s.add_dependency(%q<jeweler>, [">= 0"])
77
+ s.add_dependency(%q<cucumber>, [">= 0"])
78
+ s.add_dependency(%q<jeweler>, [">= 0"])
79
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
80
+ s.add_dependency(%q<thor>, ["~> 0.11.0"])
81
+ s.add_dependency(%q<cucumber>, [">= 0"])
82
+ s.add_dependency(%q<jeweler>, [">= 0"])
83
+ s.add_dependency(%q<ruby-debug19>, [">= 0"])
84
+ end
85
+ end
86
+
@@ -0,0 +1,192 @@
1
+ require "thor"
2
+ require "uri"
3
+ require "csv"
4
+
5
+ class Gip < Thor
6
+ VERSION = "0.2.2"
7
+
8
+ map %w(--version -v) => :version, %w(--help -h) => :help
9
+
10
+ desc "Prints version information", ""
11
+ def version
12
+ puts "Gip v#{VERSION}"
13
+ end
14
+
15
+ desc "import REPOSITORY_URL [path]", <<DESC
16
+ Imports the repository at path in the current tree.
17
+
18
+ If path is absent, the repository's base name will be used.
19
+ --remote specifies the name of the remote. If unspecified, the repository's base name will be used.
20
+ --commit specifies which commit to import. If unspecified, 'REMOTE/master' will be used. You can use any <tree-ish> that Git will recognize (SHA-1, branch name, tag name). The remote's name will always be prefixed to this value.
21
+
22
+ In all cases, a .gipinfo file will be created/updated with the correct remotes specified. The .gipinfo file is a CSV file with 2 columns: remote name,repository URL.
23
+ DESC
24
+ method_options :commit => :string, :remote => :string, :verbose => 0
25
+ def import(repository_url, path=nil)
26
+ uri = begin
27
+ URI.parse(repository_url)
28
+ rescue URI::InvalidURIError
29
+ URI.parse("git://" + repository_url.split("@", 2).last.split(":", 2).join("/"))
30
+ end
31
+ path = File.basename(uri.path).sub(File.extname(uri.path), "") unless path
32
+ name = options[:remote]
33
+ name = File.basename(uri.path).sub(File.extname(uri.path), "") unless name
34
+
35
+ remote = Remote.new(name, repository_url, path)
36
+ commit = extract_commit(remote)
37
+ puts "Importing #{remote.url} into #{remote.path} at #{commit}"
38
+
39
+ create_remote remote.name, remote.url
40
+ git :fetch, remote.name
41
+ git :"read-tree", "--prefix=#{remote.path}/", "-u", commit
42
+ gipinfo(remote)
43
+ git :add, ".gipinfo"
44
+ git :commit, "-m", "Vendored #{repository_url} at #{commit}", :verbose => true
45
+ end
46
+
47
+ desc "Creates or updates remotes in this repository", <<DESC
48
+ Given the remotes described in a .gipinfo, creates or updates Git remotes in this repository.
49
+ DESC
50
+ method_options :verbose => 0
51
+ def remotify
52
+ read_gipinfo.each do |remote|
53
+ create_remote(remote.name, remote.url)
54
+ git :fetch, remote.name
55
+ end
56
+ end
57
+
58
+ desc "Freshens the tree at PATH", <<DESC
59
+ Given a previously imported tree at PATH, updates it to the latest HEAD, or whatever --commit specifies.
60
+
61
+ --commit defaults to 'master', and will always be prefixed with the remote's name.
62
+ DESC
63
+ method_options :verbose => 0, :commit => :string
64
+ def update(path=nil)
65
+ read_gipinfo.each do |remote|
66
+ next unless remote.path == path
67
+ commit = extract_commit(remote)
68
+ puts "Freshening #{remote.path} from #{remote.url} to #{commit}"
69
+
70
+ create_remote remote.name, remote.url
71
+ git :fetch, remote.name
72
+ git :merge, "-s", :subtree, "#{remote.name}/#{commit}", :verbose => true
73
+ end
74
+ end
75
+
76
+ private
77
+ def extract_commit(remote)
78
+ commit = options[:commit]
79
+ commit = "master" unless commit
80
+ commit = "#{remote.name}/#{commit}"
81
+ end
82
+
83
+ def create_remote(remote_name, repository_url)
84
+ git :remote, :add, remote_name, repository_url
85
+ rescue CommandError => e
86
+ # 128 means remote already exists
87
+ raise unless e.exitstatus == 128
88
+ end
89
+
90
+ def gipinfo(remote)
91
+ info = read_gipinfo
92
+ info << remote
93
+ write_gipinfo(info)
94
+ end
95
+
96
+ def read_gipinfo
97
+ if File.file?(".gipinfo")
98
+ CSV.read(".gipinfo").inject(Array.new) do |memo, (name, url, path)|
99
+ next memo if name =~ /^\s*#/
100
+ memo << Remote.new(name, url, path)
101
+ end
102
+ else
103
+ Array.new
104
+ end
105
+ end
106
+
107
+ def write_gipinfo(remotes)
108
+ CSV.open(".gipinfo", "w") do |io|
109
+ io << ["# This is the GIP gipinfo file. See http://github.com/francois/gip for details. Gip is a RubyGem: sudo gem install francois-gip."]
110
+ io << ["# This file maps a series of remote names to repository URLs. This file is here to ease the work of your team."]
111
+ io << ["# Run 'gip remotify' to generate the appropriate remotes in your repository."]
112
+
113
+ remotes.each do |remote|
114
+ io << remote.to_a
115
+ end
116
+ end
117
+ end
118
+
119
+ def git(*args)
120
+ run_cmd :git, *args
121
+ end
122
+
123
+ def run_cmd(executable, *args)
124
+ opts = args.last.is_a?(Hash) ? args.pop : Hash.new
125
+
126
+ args.collect! {|arg| arg.to_s =~ /\s|\*|\?|"|\n|\r/ ? %Q('#{arg}') : arg}
127
+ args.collect! {|arg| arg ? arg : '""'}
128
+ cmd = %Q|#{executable} #{args.join(' ')}|
129
+ p cmd if options[:verbose] > 0
130
+
131
+ original_language = ENV["LANGUAGE"]
132
+ begin
133
+ ENV["LANGUAGE"] = "C"
134
+ value = run_real(cmd)
135
+ p value if options[:verbose] > 1 && !value.to_s.strip.empty?
136
+ puts value if opts[:verbose]
137
+ return value
138
+ ensure
139
+ ENV["LANGUAGE"] = original_language
140
+ end
141
+ end
142
+
143
+ begin
144
+ raise LoadError, "Not implemented on Win32 machines" if RUBY_PLATFORM =~ /mswin32/
145
+ require "open4"
146
+
147
+ def run_real(cmd)
148
+ begin
149
+ pid, stdin, stdout, stderr = Open4::popen4(cmd)
150
+ _, cmdstatus = Process.waitpid2(pid)
151
+ raise CommandError.new("#{cmd.inspect} exited with status: #{cmdstatus.exitstatus}\n#{stderr.read}", cmdstatus) unless cmdstatus.success? || cmdstatus.exitstatus == 1
152
+ return stdout.read
153
+ rescue Errno::ENOENT
154
+ raise BadCommand, cmd.inspect
155
+ end
156
+ end
157
+
158
+ rescue LoadError
159
+ # On platforms where open4 is unavailable, we fallback to running using
160
+ # the backtick method of Kernel.
161
+ def run_real(cmd)
162
+ out = `#{cmd}`
163
+ raise BadCommand, cmd.inspect if $?.exitstatus == 127
164
+ raise CommandError.new("#{cmd.inspect} exited with status: #{$?.exitstatus}", $?) unless $?.success? || $?.exitstatus == 1
165
+ out
166
+ end
167
+ end
168
+
169
+ class BadCommand < StandardError; end
170
+ class CommandError < StandardError
171
+ def initialize(message, status)
172
+ super(message)
173
+ @status = status
174
+ end
175
+
176
+ def exitstatus
177
+ @status.exitstatus
178
+ end
179
+ end
180
+
181
+ class Remote
182
+ attr_accessor :name, :url, :path
183
+
184
+ def initialize(name, url, path)
185
+ @name, @url, @path = name, url, path
186
+ end
187
+
188
+ def to_a
189
+ [@name, @url, @path]
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class GipTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'gip'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,227 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gip
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - François Beausoleil
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-01 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: gip
16
+ requirement: &2152393600 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2152393600
25
+ - !ruby/object:Gem::Dependency
26
+ name: cucumber
27
+ requirement: &2152391940 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2152391940
36
+ - !ruby/object:Gem::Dependency
37
+ name: jeweler
38
+ requirement: &2152368980 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2152368980
47
+ - !ruby/object:Gem::Dependency
48
+ name: cucumber
49
+ requirement: &2152366940 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2152366940
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &2152364420 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2152364420
69
+ - !ruby/object:Gem::Dependency
70
+ name: cucumber
71
+ requirement: &2152362740 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2152362740
80
+ - !ruby/object:Gem::Dependency
81
+ name: jeweler
82
+ requirement: &2152352220 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *2152352220
91
+ - !ruby/object:Gem::Dependency
92
+ name: ruby-debug19
93
+ requirement: &2152349060 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *2152349060
102
+ - !ruby/object:Gem::Dependency
103
+ name: cucumber
104
+ requirement: &2152346820 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *2152346820
113
+ - !ruby/object:Gem::Dependency
114
+ name: jeweler
115
+ requirement: &2152344980 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *2152344980
124
+ - !ruby/object:Gem::Dependency
125
+ name: ruby-debug19
126
+ requirement: &2152330160 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *2152330160
135
+ - !ruby/object:Gem::Dependency
136
+ name: thor
137
+ requirement: &2152328600 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ~>
141
+ - !ruby/object:Gem::Version
142
+ version: 0.11.0
143
+ type: :runtime
144
+ prerelease: false
145
+ version_requirements: *2152328600
146
+ - !ruby/object:Gem::Dependency
147
+ name: cucumber
148
+ requirement: &2152327680 !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: *2152327680
157
+ - !ruby/object:Gem::Dependency
158
+ name: jeweler
159
+ requirement: &2152326200 !ruby/object:Gem::Requirement
160
+ none: false
161
+ requirements:
162
+ - - ! '>='
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: *2152326200
168
+ - !ruby/object:Gem::Dependency
169
+ name: ruby-debug19
170
+ requirement: &2152325000 !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ type: :development
177
+ prerelease: false
178
+ version_requirements: *2152325000
179
+ description:
180
+ email: francois@teksol.info
181
+ executables:
182
+ - gip
183
+ extensions: []
184
+ extra_rdoc_files:
185
+ - LICENSE
186
+ - README.rdoc
187
+ files:
188
+ - .document
189
+ - Gemfile
190
+ - LICENSE
191
+ - README.rdoc
192
+ - Rakefile
193
+ - VERSION
194
+ - bin/gip
195
+ - features/import.feature
196
+ - features/step_definitions/gip_steps.rb
197
+ - features/support/command_line.rb
198
+ - features/support/env.rb
199
+ - gip.gemspec
200
+ - lib/gip.rb
201
+ - test/gip_test.rb
202
+ - test/test_helper.rb
203
+ homepage: http://github.com/francois/gip
204
+ licenses: []
205
+ post_install_message:
206
+ rdoc_options: []
207
+ require_paths:
208
+ - lib
209
+ required_ruby_version: !ruby/object:Gem::Requirement
210
+ none: false
211
+ requirements:
212
+ - - ! '>='
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ required_rubygems_version: !ruby/object:Gem::Requirement
216
+ none: false
217
+ requirements:
218
+ - - ! '>='
219
+ - !ruby/object:Gem::Version
220
+ version: '0'
221
+ requirements: []
222
+ rubyforge_project:
223
+ rubygems_version: 1.8.6
224
+ signing_key:
225
+ specification_version: 3
226
+ summary: ! 'Gip into place: Piston without the SVN cruft'
227
+ test_files: []