fido 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (6) hide show
  1. data/README.md +75 -0
  2. data/bin/fido +32 -0
  3. data/fido.gemspec +29 -0
  4. data/lib/fido.rb +55 -0
  5. data/spec/fido_spec.rb +115 -0
  6. metadata +59 -0
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # Fido - he fetches
2
+
3
+ ## Install
4
+
5
+ gem install fido -s http://gemcutter.org
6
+
7
+ ## Usage
8
+
9
+ $ fido git://github.com/sinatra/sinatra.git
10
+ $ cd sinatra
11
+ $ git branch
12
+ * master
13
+ $ git log --format=%h | head -n1
14
+ 6d8b333
15
+
16
+ The second run will perform no operation because it's already been fetched.
17
+ This is for safety so any local work isn't interupted
18
+
19
+ $ .. add file and commit
20
+ $ cd ..
21
+ $ fido git://github.com/sinatra/sinatra.git
22
+ $ git log --format=%h | head -n1
23
+ 71435b7
24
+
25
+ ## Branch failover
26
+ This is where fido becomes interesting
27
+
28
+ $ fido git://github.com/sinatra/sinatra.git foo 0.3.x bar baz
29
+ $ cd sinatra
30
+ $ git branch
31
+ * 0.3.x
32
+
33
+ We told fido we want to clone the sinatra repo and checkout one branch
34
+ with preference to `foo` if `origin/foo`, then `0.3.x`, etc.
35
+
36
+ ## Destruction
37
+ After fido has fetched a repo he knows that it can be bad to interupt
38
+ any local work. He can be told destruction is ok.
39
+
40
+ $ fido git://github.com/sinatra/sinatra.git foo 0.3.x bar baz
41
+ $ cd sinatra
42
+ $ git branch
43
+ * 0.3.x
44
+
45
+ $ cd ..
46
+ $ fido git://github.com/sinatra/sinatra.git -f 0.9.x
47
+ $ cd sinatra
48
+ $ git branch
49
+ 0.3.x
50
+ * 0.9.x
51
+
52
+ ## LICENSE
53
+
54
+ Copyright (c) 2009 Blake Mizerany
55
+
56
+ Permission is hereby granted, free of charge, to any person
57
+ obtaining a copy of this software and associated documentation
58
+ files (the "Software"), to deal in the Software without
59
+ restriction, including without limitation the rights to use,
60
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
61
+ copies of the Software, and to permit persons to whom the
62
+ Software is furnished to do so, subject to the following
63
+ conditions:
64
+
65
+ The above copyright notice and this permission notice shall be
66
+ included in all copies or substantial portions of the Software.
67
+
68
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
69
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
70
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
71
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
72
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
73
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
74
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
75
+ OTHER DEALINGS IN THE SOFTWARE.
data/bin/fido ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
3
+ require 'optparse'
4
+ require 'fido'
5
+
6
+ debug = false
7
+ force = false
8
+
9
+ ARGV.options do |o|
10
+ o.banner = "Usage: fido <git-url> [branch[, work, bug123]]"
11
+ o.separator "\n"
12
+ o.separator " This example will clone <git-url> and checkout"
13
+ o.separator " to work if origin/work exists otherwise origin/bug123"
14
+ o.separator " or origin/master (implied)"
15
+ o.separator "\n"
16
+ o.on_tail("-f", "--force", "destructive fetch") { force = true }
17
+ o.on_tail("-h", "--help", "Show this message") { abort(o.to_s) }
18
+ o.on_tail("-d", "--debug", "Show debug information") { debug = true }
19
+ o.parse!
20
+
21
+ abort(o.to_s) if ARGV.empty?
22
+ end
23
+
24
+ ARGV << force if force
25
+
26
+ if debug
27
+ Fido.new(Logger.new(STDOUT))
28
+ else
29
+ Fido.new
30
+ end.clone(*ARGV)
31
+
32
+ #vim: syn=ruby
data/fido.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ Gem::Specification.new do |s|
2
+ s.specification_version = 2 if s.respond_to? :specification_version=
3
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
4
+
5
+ s.name = 'fido'
6
+ s.version = '0.1.0'
7
+ s.date = '2009-10-30'
8
+
9
+ s.description = "Fido - he fetches"
10
+ s.summary = s.description
11
+
12
+ s.authors = ["Blake Mizerany"]
13
+ s.email = "blake.mizerany@gmail.com"
14
+
15
+ s.files = %w[
16
+ README.md
17
+ fido.gemspec
18
+ lib/fido.rb
19
+ bin/fido
20
+ spec/fido_spec.rb
21
+ ]
22
+ s.executables = ['fido']
23
+
24
+ s.extra_rdoc_files = %w[README.md]
25
+
26
+ s.homepage = "http://github.com/bmizerany/fido/"
27
+ s.require_paths = %w[lib]
28
+ s.rubygems_version = '1.1.1'
29
+ end
data/lib/fido.rb ADDED
@@ -0,0 +1,55 @@
1
+ require 'fileutils'
2
+ require 'open3'
3
+ require 'logger'
4
+ require 'hutils/logable'
5
+
6
+ class Fido
7
+ include FileUtils
8
+ include Logable
9
+
10
+ def clone(repo, *to)
11
+ force = to.last == true && to.pop
12
+ to << "master"
13
+
14
+ dir = File.basename(repo, ".git")
15
+ mkdir_p dir
16
+
17
+ cd dir do
18
+ return if !force && File.exists?(".git/FIDO")
19
+
20
+ if !File.exists?(".git")
21
+ cmd "git init"
22
+ cmd "git remote add origin #{repo}"
23
+ end
24
+
25
+ cmd "git fetch origin"
26
+
27
+ branches = cmd("git branch -a")
28
+
29
+ to.each do |branch|
30
+ if branches =~ /\* #{branch}\n/
31
+ cmd "git reset --hard origin/#{branch}"
32
+ break
33
+ elsif branches =~ / remotes\/origin\/#{branch}\n/
34
+ cmd "git branch -D #{branch}" if branches =~ / #{branch}\n/
35
+ cmd "git checkout -b #{branch} origin/#{branch}"
36
+ break
37
+ end
38
+ end
39
+
40
+ touch ".git/FIDO"
41
+ end
42
+ end
43
+
44
+ def cmd(c)
45
+ out, err = nil
46
+ @logger.debug c
47
+ Open3.popen3(c) do |_i, o, e|
48
+ out = o.read
49
+ err = e.read
50
+ end
51
+ @logger.debug out if out !~ /^\s*$/
52
+ @logger.error err if err !~ /^\s*$/
53
+ out
54
+ end
55
+ end
data/spec/fido_spec.rb ADDED
@@ -0,0 +1,115 @@
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
2
+ require 'fido'
3
+ require 'recho'
4
+
5
+ GitDir = File.expand_path(File.dirname(__FILE__) + "/git")
6
+ TestRepo = GitDir + "/test-repo.git"
7
+
8
+ include FileUtils
9
+
10
+ describe "Fido" do
11
+
12
+ def lastSHA
13
+ `git log --format=%H | head -n1`.chomp
14
+ end
15
+
16
+ before do
17
+ @fido = if $DEBUG
18
+ Fido.new(Logger.new(STDOUT))
19
+ else
20
+ Fido.new
21
+ end
22
+
23
+ @pwd = pwd
24
+
25
+ mkdir_p TestRepo
26
+
27
+ cd TestRepo do
28
+ `git init`
29
+ echo("foo!") > "FOO"
30
+ `git add FOO`
31
+ `git commit -m 'foo'`
32
+ end
33
+
34
+ cd GitDir
35
+ end
36
+
37
+ after { cd @pwd ; rm_rf GitDir }
38
+
39
+ it "clones a repo and leaves it at master by default" do
40
+ @fido.clone(TestRepo)
41
+ cd "test-repo" do
42
+ `git branch`.should =~ /\* master/
43
+ end
44
+ end
45
+
46
+ it "does a checkout of the first branch if available" do
47
+ cd TestRepo do
48
+ `git branch first`
49
+ end
50
+ @fido.clone(TestRepo, "first")
51
+ cd "test-repo" do
52
+ `git branch`.should =~ /\* first/
53
+ end
54
+ end
55
+
56
+ it "does a checkout of the second branch if first is not available" do
57
+ cd TestRepo do
58
+ `git branch second`
59
+ end
60
+ @fido.clone(TestRepo, "first", "second")
61
+ cd "test-repo" do
62
+ `git branch`.should =~ /\* second/
63
+ end
64
+ end
65
+
66
+ it "drops a FIDO file one clone" do
67
+ @fido.clone(TestRepo)
68
+ cd "test-repo" do
69
+ File.exists?(".git/FIDO").should == true
70
+ end
71
+ end
72
+
73
+ it "does nothing if .git/FIDO exists" do
74
+ cd TestRepo do
75
+ `git branch some-work`
76
+ end
77
+
78
+ @fido.clone(TestRepo)
79
+
80
+ cd "test-repo" do
81
+ `git checkout -b stay-here 2>/dev/null`
82
+ end
83
+
84
+ @fido.clone(TestRepo, "some-work")
85
+
86
+ cd "test-repo" do
87
+ `git branch`.should =~ /\* stay-here/
88
+ end
89
+ end
90
+
91
+ it "will mirror upstream if forced" do
92
+ sha = nil
93
+
94
+ cd TestRepo do
95
+ echo("foo") >> "FOO"
96
+ `git add FOO`
97
+ `git commit -m 'foo'`
98
+ sha = lastSHA
99
+ end
100
+
101
+ @fido.clone(TestRepo)
102
+
103
+ cd "test-repo" do
104
+ echo("bar") >> "BAR"
105
+ `git add BAR`
106
+ `git commit -m 'foo'`
107
+ end
108
+
109
+ @fido.clone(TestRepo, true)
110
+
111
+ cd "test-repo" do
112
+ lastSHA.should == sha
113
+ end
114
+ end
115
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fido
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Blake Mizerany
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-30 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Fido - he fetches
17
+ email: blake.mizerany@gmail.com
18
+ executables:
19
+ - fido
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.md
24
+ files:
25
+ - README.md
26
+ - fido.gemspec
27
+ - lib/fido.rb
28
+ - bin/fido
29
+ - spec/fido_spec.rb
30
+ has_rdoc: true
31
+ homepage: http://github.com/bmizerany/fido/
32
+ licenses: []
33
+
34
+ post_install_message:
35
+ rdoc_options: []
36
+
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.3.4
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: Fido - he fetches
58
+ test_files: []
59
+