obazoud-git-external 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/bin/git-external +196 -0
  2. metadata +68 -0
data/bin/git-external ADDED
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ $root_dir = `git rev-parse --show-toplevel`.chomp
5
+ $externals_file = "#{$root_dir}/.gitexternals"
6
+ $ignore_file = "#{$root_dir}/.gitignore"
7
+ $configurations = {}
8
+
9
+ def usage
10
+ puts "Usage: git external add <repository-url> <path> [<branch>]"
11
+ puts " or: git external status"
12
+ puts " or: git external init [--] [<path>...]"
13
+ puts " or: git external update [--] [<path>...]"
14
+ puts " or: git external cmd '<command>'"
15
+ puts " or: git external list"
16
+ end
17
+
18
+ def load_configuration
19
+ if File.file? $externals_file
20
+ lines = `git config -l -f #{$externals_file}`.split(/\n/)
21
+ $configurations = {}
22
+ lines.each do |line|
23
+ if line =~ /^external\.([^$]+)\.([^=]+)=(.*)$/
24
+ $configurations[$1.chomp] ||= {}
25
+ $configurations[$1.chomp][$2.chomp] = $3.chomp
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def print_configuration
32
+ $configurations.each do |name, config|
33
+ puts name
34
+ config.each do |key, value|
35
+ puts "\t#{key}: #{value}"
36
+ end
37
+ end
38
+ end
39
+
40
+ def normalize_url(url)
41
+ if url =~ /^\./
42
+ origin_url = `git config --get remote.origin.url`.chomp
43
+
44
+ unless origin_url =~ /^\w+:\/\//
45
+ if origin_url =~ /^([^:\/]+):([^:]+)/
46
+ origin_url = "ssh://#{$1}/#{$2}"
47
+ end
48
+ end
49
+
50
+ require 'uri'
51
+ uri = URI.parse URI.encode origin_url
52
+ uri.path = File.expand_path(url, uri.path)
53
+ uri.to_s
54
+ else
55
+ url
56
+ end
57
+ end
58
+
59
+ # Check if a branch exists
60
+ def branch_exists(path, branch)
61
+ branches = `cd #{path}; git branch`
62
+ regex = Regexp.new('[\\n\\s\\*]+' + Regexp.escape(branch.to_s) + '\\n')
63
+ result = ((branches =~ regex) ? true : false)
64
+ return result
65
+ end
66
+
67
+ def init_external(url, path, branch='master')
68
+ require 'fileutils'
69
+ if File.directory? "#{path}/.git"
70
+ puts "- Repository already exists"
71
+ else
72
+ FileUtils.makedirs File.dirname(path)
73
+ url = normalize_url url
74
+ system "git clone #{url} #{path}"
75
+
76
+ # Create a local tracking branch if it doesn't exist already
77
+ unless branch_exists(path, branch)
78
+ puts "- Creating local tracking branch: #{branch} -> origin/#{branch}"
79
+ system "cd #{path}; git branch checkout --track #{branch} origin/#{branch}"
80
+ end
81
+
82
+ # Check out the local branch
83
+ puts "- Checkout local branch: #{branch}"
84
+ system "cd #{path}; git checkout #{branch}"
85
+ end
86
+ end
87
+
88
+ def update_external(url, path, branch='master')
89
+ require 'fileutils'
90
+ if File.directory? "#{path}/.git"
91
+ `cd #{path}; git pull origin #{branch}`
92
+ end
93
+ end
94
+
95
+ def execute(cmd)
96
+ values = []
97
+ IO.popen(cmd) do |f|
98
+ tmp = f.gets
99
+ values.push(tmp.gsub(/\r/, '').gsub(/\n/, '')) unless tmp.nil?
100
+ end
101
+ return $?.exitstatus, values
102
+ end
103
+
104
+ def command_status
105
+ ok = 0
106
+ broken = 0
107
+ $configurations.each do |name, config|
108
+ branch = config["branch"]
109
+ url = config["url"]
110
+ path = config["path"]
111
+
112
+ gitBranchExit, gitBranch = execute("cd #{path} && git config \"branch.$(git symbolic-ref HEAD --short).merge\" | sed \"s/refs\\/heads\\///g\"")
113
+ gitRemoteExit, gitRemote = execute("cd #{path} && git config \"remote.$(git config \"branch.$(git symbolic-ref HEAD --short).remote\").url\"");
114
+
115
+ if gitBranchExit != 0 && gitRemoteExit != 0
116
+ puts " ✗ #{path}: exit code #{gitBranchExit}, #{gitRemoteExit}"
117
+ broken += 1
118
+ else
119
+ if branch == gitBranch[0]
120
+ if url == gitRemote[0]
121
+ puts " ✓ #{path}"
122
+ ok += 1
123
+ else
124
+ puts " ✗ #{path} -- expected url '#{url}' but was '#{gitRemote[0]}'"
125
+ broken +=1
126
+ end
127
+ else
128
+ puts " ✗ #{path} -- expected branch '#{branch}' but was '#{gitBranch[0]}'"
129
+ broken +=1
130
+ end
131
+ end
132
+ end
133
+ puts "#{broken > 0 ? "✗" : "✓"} » #{ok} ok • #{broken} broken"
134
+ end
135
+
136
+ def command_add(url, path, branch='master')
137
+ command_rm(path)
138
+ `git config -f #{$externals_file} --add external.#{path}.path #{path}`
139
+ `git config -f #{$externals_file} --add external.#{path}.url #{url}`
140
+ `git config -f #{$externals_file} --add external.#{path}.branch #{branch}`
141
+ `echo "#{path}" >> #{$ignore_file}`
142
+ end
143
+
144
+ def command_rm(path)
145
+ if File.file? $externals_file
146
+ `git config -f #{$externals_file} --unset external.#{path}.path`
147
+ `git config -f #{$externals_file} --unset external.#{path}.url`
148
+ `git config -f #{$externals_file} --unset external.#{path}.branch`
149
+ `git config -f #{$externals_file} --remove-section external.#{path} > /dev/null 2>&1`
150
+ File.delete $externals_file if `wc -l #{$externals_file}`.chomp.to_i == 0
151
+ end
152
+ if File.file? $ignore_file
153
+ # Remove entry from .gitignore file
154
+ `perl -pi -e 's/\\Q#{path.gsub(/\//, '\/')}\\E\n//g' #{$ignore_file}`
155
+ end
156
+ end
157
+
158
+ def command_init
159
+ $configurations.each do |name, config|
160
+ puts name
161
+ init_external config["url"], config["path"], config["branch"]
162
+ end
163
+ end
164
+
165
+ def command_update
166
+ $configurations.each do |name, config|
167
+ update_external config["url"], config["path"], config["branch"]
168
+ end
169
+ end
170
+
171
+ def command_cmd(cmd)
172
+ $configurations.each do |name, config|
173
+ path = config['path']
174
+ system("echo #{path}; cd #{path}; #{cmd}")
175
+ end
176
+ end
177
+
178
+ def command_list
179
+ print_configuration
180
+ end
181
+
182
+ load_configuration
183
+
184
+ command=ARGV[0]
185
+
186
+ case command
187
+ when "status" then command_status
188
+ when "add" then command_add ARGV[1], ARGV[2], ARGV[3] || "master"
189
+ when "rm" then command_rm ARGV[1]
190
+ when "init" then command_init
191
+ when "update" then command_update
192
+ when "cmd" then command_cmd ARGV[1]
193
+ when "list" then command_list
194
+ else usage
195
+ end
196
+
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: obazoud-git-external
3
+ version: !ruby/object:Gem::Version
4
+ hash: 17
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 5
10
+ version: 0.1.5
11
+ platform: ruby
12
+ authors:
13
+ - Daniel Cestari
14
+ - Olivier Bazoud
15
+ - Alastair Harrison
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2012-10-24 00:00:00 Z
21
+ dependencies: []
22
+
23
+ description: Extension for git which adds a command providing similar functionality to git submodules but without attaching each module to a single version
24
+ email:
25
+ - olivier.bazoud@gmail.com
26
+ executables:
27
+ - git-external
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - bin/git-external
34
+ homepage: http://github.com/obazoud/git-external
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.24
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Git version of an svn:external, an alternative to Git Submodule
67
+ test_files: []
68
+