obazoud-git-external 0.1.5

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 (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
+