ext 1.0.2 → 1.0.3
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.
- data/CHANGELOG +5 -0
- data/README +55 -15
- data/lib/externals/configuration/configuration.rb +8 -0
- data/lib/externals/ext.rb +130 -34
- data/lib/externals/extensions/string.rb +31 -1
- data/lib/externals/project.rb +4 -0
- data/lib/externals/scms/git_project.rb +37 -4
- data/lib/externals/scms/svn_project.rb +121 -17
- data/lib/externals/test_case.rb +210 -8
- data/test/test_checkout_with_subprojects_git.rb +52 -1
- data/test/test_projects.rb +10 -0
- data/test/test_string_extensions.rb +32 -0
- data/test/test_svn_branches.rb +501 -0
- metadata +6 -4
@@ -3,25 +3,33 @@ require File.join(File.dirname(__FILE__), '..', 'project')
|
|
3
3
|
module Externals
|
4
4
|
class SvnProject < Project
|
5
5
|
def default_branch
|
6
|
-
|
6
|
+
raise "There is no default_branch for SvnProject"
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
def
|
11
|
-
|
9
|
+
public
|
10
|
+
def co *args
|
11
|
+
# delete path if not empty
|
12
|
+
rmdircmd = "rmdir #{path}"
|
13
|
+
`#{rmdircmd}` if File.exists? path
|
12
14
|
|
13
|
-
|
15
|
+
if File.exists? path
|
16
|
+
up
|
17
|
+
else
|
18
|
+
opts = resolve_opts "co"
|
14
19
|
|
15
|
-
|
16
|
-
puts(svncocmd = "svn #{opts} co #{repository} #{path}")
|
17
|
-
puts `#{svncocmd}`
|
20
|
+
url = repository
|
18
21
|
|
19
|
-
|
20
|
-
|
22
|
+
if branch
|
23
|
+
require_repository
|
24
|
+
url = [url, branch].join("/")
|
25
|
+
end
|
21
26
|
|
22
|
-
|
23
|
-
|
24
|
-
|
27
|
+
puts(svncocmd = "svn #{opts} co #{url} #{path}")
|
28
|
+
puts `#{svncocmd}`
|
29
|
+
raise unless $? == 0
|
30
|
+
|
31
|
+
change_to_revision "co"
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
35
|
def change_to_revision command = ""
|
@@ -35,10 +43,17 @@ module Externals
|
|
35
43
|
end
|
36
44
|
|
37
45
|
def ex *args
|
46
|
+
# delete path if not empty
|
38
47
|
(rmdircmd = "rmdir #{path}")
|
48
|
+
`#{rmdircmd}`
|
39
49
|
|
40
50
|
url = repository
|
41
51
|
|
52
|
+
if branch
|
53
|
+
require_repository
|
54
|
+
url = [url, branch].join("/")
|
55
|
+
end
|
56
|
+
|
42
57
|
if revision
|
43
58
|
url += "@#{revision}"
|
44
59
|
end
|
@@ -48,9 +63,32 @@ module Externals
|
|
48
63
|
puts `#{svncocmd}`
|
49
64
|
end
|
50
65
|
|
66
|
+
def switch branch_name, options = {}
|
67
|
+
require_repository
|
68
|
+
if current_branch != branch_name
|
69
|
+
Dir.chdir path do
|
70
|
+
url = [repository, branch_name].join("/")
|
71
|
+
`svn #{scm_opts} switch #{url}`
|
72
|
+
unless $? == 0
|
73
|
+
raise "Could not switch to #{url}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
51
79
|
def up *args
|
80
|
+
# delete path if not empty
|
81
|
+
rmdircmd = "rmdir #{path}"
|
82
|
+
`#{rmdircmd}` if File.exists? path
|
83
|
+
|
84
|
+
|
52
85
|
if File.exists? path
|
53
86
|
puts "updating #{path}:"
|
87
|
+
|
88
|
+
if branch
|
89
|
+
switch branch
|
90
|
+
end
|
91
|
+
|
54
92
|
if revision
|
55
93
|
change_to_revision "up"
|
56
94
|
else
|
@@ -59,7 +97,7 @@ module Externals
|
|
59
97
|
end
|
60
98
|
end
|
61
99
|
else
|
62
|
-
|
100
|
+
co
|
63
101
|
end
|
64
102
|
end
|
65
103
|
|
@@ -86,9 +124,12 @@ module Externals
|
|
86
124
|
false
|
87
125
|
end
|
88
126
|
|
89
|
-
def self.fill_in_opts opts, main_options, sub_options
|
90
|
-
opts.on("--svn", "--subversion",
|
91
|
-
Integer
|
127
|
+
def self.fill_in_opts opts, main_options, sub_options, options = {}
|
128
|
+
opts.on("--svn", "--subversion",
|
129
|
+
Integer,
|
130
|
+
*"same as '--scm svn' Uses subversion to
|
131
|
+
checkout/export the main project".lines_by_width(options[:summary_width])
|
132
|
+
) {sub_options[:scm] = main_options[:scm] = 'svn'}
|
92
133
|
end
|
93
134
|
|
94
135
|
def self.detected?
|
@@ -108,6 +149,54 @@ module Externals
|
|
108
149
|
ignore_text(path) =~ Regexp.new("^\\s*#{File.basename(path)}\\s*$")
|
109
150
|
end
|
110
151
|
|
152
|
+
def current_branch
|
153
|
+
require_repository
|
154
|
+
branch = info_url.gsub(repository, "")
|
155
|
+
if branch == repository
|
156
|
+
raise "Could not determine branch from URL #{info_url}.
|
157
|
+
Does not appear have a substring of #{repository}"
|
158
|
+
end
|
159
|
+
if branch !~ /^\//
|
160
|
+
raise "Was expecting the branch and repository to be separated by '/'
|
161
|
+
Please file an issue about this at http://github.com/azimux/externals"
|
162
|
+
end
|
163
|
+
branch.gsub(/^\//, "")
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.extract_repository url, branch
|
167
|
+
repository = url.gsub(branch, "")
|
168
|
+
if url == repository
|
169
|
+
raise "Could not determine repository from URL #{info_url}.
|
170
|
+
Does not appear to have the branch #{branch} as a substring"
|
171
|
+
end
|
172
|
+
if repository !~ /\/$/
|
173
|
+
raise "Was expecting the branch and repository to be separated by '/'
|
174
|
+
Please file an issue about this at http://github.com/azimux/externals"
|
175
|
+
end
|
176
|
+
repository.gsub(/\/$/, "")
|
177
|
+
end
|
178
|
+
|
179
|
+
def require_repository
|
180
|
+
if repository.nil? || repository.empty?
|
181
|
+
url = info_url
|
182
|
+
url = "svn+ssh://server/path/repository" unless url
|
183
|
+
puts "to use any branching features with a subversion project, the
|
184
|
+
repository must be present in the .externals file.
|
185
|
+
|
186
|
+
See http://nopugs.com/ext-svn-branches for more info
|
187
|
+
|
188
|
+
The name of the branch should be excluded from the repository URL.
|
189
|
+
|
190
|
+
You might need to change your .externals file to contain something like this:
|
191
|
+
|
192
|
+
[.]
|
193
|
+
scm = svn
|
194
|
+
repository = #{info_url}
|
195
|
+
"
|
196
|
+
raise "Cannot use subversion branching features without a repository in .externals file"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
111
200
|
def append_ignore path
|
112
201
|
parent = File.dirname(path)
|
113
202
|
child = File.basename(path)
|
@@ -120,6 +209,7 @@ module Externals
|
|
120
209
|
|
121
210
|
Dir.chdir(parent) do
|
122
211
|
puts `svn #{scm_opts} propset svn:ignore "#{rows.compact.join("\n")}\n" .`
|
212
|
+
raise "Could not ignore path, something went wrong in svn." unless $? == 0
|
123
213
|
end
|
124
214
|
end
|
125
215
|
|
@@ -167,6 +257,20 @@ module Externals
|
|
167
257
|
end
|
168
258
|
end
|
169
259
|
|
260
|
+
def self.info_url scm_opts = ""
|
261
|
+
if `svn #{scm_opts} info` =~ /^\s*URL:\s*([^\s]+)\s*$/
|
262
|
+
$1
|
263
|
+
else
|
264
|
+
raise "Could not get URL from svn info"
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def info_url
|
269
|
+
Dir.chdir path do
|
270
|
+
self.class.info_url scm_opts
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
170
274
|
def freeze_involves_branch?
|
171
275
|
false
|
172
276
|
end
|
data/lib/externals/test_case.rb
CHANGED
@@ -80,22 +80,110 @@ module Externals
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
+
def with_svn_branches_modules_repository_dir
|
84
|
+
File.expand_path(File.join(repository_dir, with_svn_branches_modules_repository_name))
|
85
|
+
end
|
86
|
+
def with_svn_branches_modules_repository_url
|
87
|
+
url = "file:///#{with_svn_branches_modules_repository_dir}"
|
88
|
+
if windows?
|
89
|
+
url.gsub!(/\\/, "/")
|
90
|
+
end
|
91
|
+
url.gsub("file:////", 'file:///')
|
92
|
+
end
|
93
|
+
def with_svn_branches_repository_url
|
94
|
+
url = "file:///#{with_svn_branches_repository_dir}"
|
95
|
+
if windows?
|
96
|
+
url.gsub!(/\\/, "/")
|
97
|
+
end
|
98
|
+
url.gsub("file:////", 'file:///')
|
99
|
+
end
|
100
|
+
|
101
|
+
def with_svn_branches_modules_repository_name
|
102
|
+
'svnmodulesbranchesrepo'
|
103
|
+
end
|
104
|
+
def with_svn_branches_repository_dir
|
105
|
+
File.expand_path(File.join(repository_dir, with_svn_branches_repository_name))
|
106
|
+
end
|
107
|
+
def with_svn_branches_repository_name
|
108
|
+
'svnbranchesrepo'
|
109
|
+
end
|
110
|
+
|
111
|
+
def destroy_with_svn_branches_modules_repository
|
112
|
+
Dir.chdir repository_dir do
|
113
|
+
`rm -rf #{with_svn_branches_modules_repository_name}`
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def destroy_with_svn_branches_repository
|
118
|
+
Dir.chdir repository_dir do
|
119
|
+
`rm -rf #{with_svn_branches_repository_name}`
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def create_with_svn_branches_modules_repository
|
124
|
+
Dir.chdir(File.join(root_dir, 'test')) do
|
125
|
+
`mkdir repositories` unless File.exists? 'repositories'
|
126
|
+
Dir.chdir repository_dir do
|
127
|
+
puts `svnadmin create #{with_svn_branches_modules_repository_name}`
|
128
|
+
end
|
129
|
+
|
130
|
+
`mkdir workdir` unless File.exists? 'workdir'
|
131
|
+
Dir.chdir 'workdir' do
|
132
|
+
cmd = "svn checkout \"#{with_svn_branches_modules_repository_url}\""
|
133
|
+
puts "about to run #{cmd}"
|
134
|
+
puts `#{cmd}`
|
135
|
+
raise unless $? == 0
|
136
|
+
|
137
|
+
Dir.chdir with_svn_branches_modules_repository_name do
|
138
|
+
`mkdir branches`
|
139
|
+
`mkdir current`
|
140
|
+
|
141
|
+
SvnProject.add_all
|
142
|
+
puts `svn commit -m "created branch directory structure"`
|
143
|
+
raise unless $? == 0
|
144
|
+
|
145
|
+
end
|
146
|
+
`rm -rf #{with_svn_branches_modules_repository_name}`
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
def create_with_svn_branches_repository
|
151
|
+
Dir.chdir(File.join(root_dir, 'test')) do
|
152
|
+
`mkdir repositories` unless File.exists? 'repositories'
|
153
|
+
Dir.chdir repository_dir do
|
154
|
+
puts `svnadmin create #{with_svn_branches_repository_name}`
|
155
|
+
end
|
156
|
+
|
157
|
+
`mkdir workdir` unless File.exists? 'workdir'
|
158
|
+
Dir.chdir 'workdir' do
|
159
|
+
cmd = "svn checkout \"#{with_svn_branches_repository_url}\""
|
160
|
+
puts "about to run #{cmd}"
|
161
|
+
puts `#{cmd}`
|
162
|
+
raise unless $? == 0
|
163
|
+
|
164
|
+
Dir.chdir with_svn_branches_repository_name do
|
165
|
+
`mkdir branches`
|
166
|
+
`mkdir current`
|
167
|
+
|
168
|
+
SvnProject.add_all
|
169
|
+
puts `svn commit -m "created branch directory structure"`
|
170
|
+
raise unless $? == 0
|
171
|
+
|
172
|
+
end
|
173
|
+
`rm -rf #{with_svn_branches_modules_repository_name}`
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
83
178
|
def destroy_test_modules_repository scm
|
84
179
|
puts(rmcmd = "rm -rf #{modules_repository_dir(scm)}")
|
85
180
|
puts `#{rmcmd}`
|
86
|
-
puts(rmcmd = "rm -rf #{modules_repository_dir(scm)}")
|
87
|
-
puts `#{rmcmd}`
|
88
181
|
end
|
89
182
|
|
90
183
|
def modules_repository_dir scm = nil
|
91
|
-
|
92
|
-
File.join(File.dirname(__FILE__), '..', '..', 'test', 'repositories')
|
93
|
-
else
|
94
|
-
File.expand_path(File.join(repository_dir, "#{scm}modulesrepo"))
|
95
|
-
end
|
184
|
+
File.expand_path(File.join(repository_dir, "#{scm}modulesrepo"))
|
96
185
|
end
|
97
186
|
|
98
|
-
|
99
187
|
def create_rails_application
|
100
188
|
Dir.mkdir applications_dir unless File.exists?(applications_dir)
|
101
189
|
Dir.chdir applications_dir do
|
@@ -139,5 +227,119 @@ module Externals
|
|
139
227
|
def rails_application_dir
|
140
228
|
File.join(applications_dir, 'rails_app')
|
141
229
|
end
|
230
|
+
|
231
|
+
def initialize_with_svn_branches_repository
|
232
|
+
Dir.chdir File.join(root_dir, 'test') do
|
233
|
+
repo_url = with_svn_branches_repository_url
|
234
|
+
|
235
|
+
Dir.chdir 'workdir' do
|
236
|
+
puts `svn co #{[repo_url, "current"].join("/")} rails_app`
|
237
|
+
raise unless $? == 0
|
238
|
+
Dir.chdir "rails_app" do
|
239
|
+
puts `cp -r #{rails_application_dir}/* .`
|
240
|
+
raise unless $? == 0
|
241
|
+
|
242
|
+
Ext.run "init", "-b", "current"
|
243
|
+
|
244
|
+
# this line is necessary as ext can't perform the necessary
|
245
|
+
# ignores otherwise if vendor and vendor/plugins haven't been added
|
246
|
+
SvnProject.add_all
|
247
|
+
|
248
|
+
raise " could not create .externals" unless File.exists? '.externals'
|
249
|
+
%w(rails acts_as_list).each do |proj|
|
250
|
+
Ext.run "install", File.join(root_dir, 'test', 'cleanreps', "#{proj}.git")
|
251
|
+
end
|
252
|
+
|
253
|
+
#install a couple svn managed subprojects
|
254
|
+
%w(foreign_key_migrations redhillonrails_core).each do |proj|
|
255
|
+
Ext.run "install", "--svn", "file:///#{File.join(root_dir, 'test', 'cleanreps', proj)}"
|
256
|
+
end
|
257
|
+
|
258
|
+
#install project with a git branch
|
259
|
+
Ext.run "install", File.join(root_dir, 'test', 'cleanreps', 'engines.git'), "-b", "edge"
|
260
|
+
|
261
|
+
#install project with a non-default path and svn branching
|
262
|
+
Ext.run "install", "--svn",
|
263
|
+
"#{with_svn_branches_modules_repository_url}",
|
264
|
+
"-b", "current",
|
265
|
+
"modules"
|
266
|
+
|
267
|
+
SvnProject.add_all
|
268
|
+
|
269
|
+
puts `svn commit -m "created empty rails app with some subprojects"`
|
270
|
+
raise unless $? == 0
|
271
|
+
|
272
|
+
# now let's make a branch in the main project called new_branch
|
273
|
+
`svn copy #{
|
274
|
+
[repo_url, "current"].join("/")
|
275
|
+
} #{[repo_url, "branches", "new_branch"].join("/")} -m "creating branch" `
|
276
|
+
raise unless $? == 0
|
277
|
+
|
278
|
+
# let's make a branch in a git subproject:
|
279
|
+
Dir.chdir File.join(%w(vendor plugins engines)) do
|
280
|
+
`git push origin master:branch1`
|
281
|
+
raise unless $? == 0
|
282
|
+
end
|
283
|
+
|
284
|
+
# let's update the .externals file in new_branch to reflect these changes
|
285
|
+
`svn switch #{[repo_url, "branches", "new_branch"].join("/")}`
|
286
|
+
raise unless $? == 0
|
287
|
+
|
288
|
+
# let's remove rails from this branch
|
289
|
+
Ext.run "uninstall", "-f", "rails"
|
290
|
+
|
291
|
+
ext = Ext.new
|
292
|
+
ext.configuration["vendor/plugins/engines"]["branch"] = "branch1"
|
293
|
+
ext.configuration["modules"]["branch"] = "branches/branch2"
|
294
|
+
ext.configuration.write
|
295
|
+
|
296
|
+
SvnProject.add_all
|
297
|
+
`svn commit -m "updated .externals to point to new branches."`
|
298
|
+
raise unless $? == 0
|
299
|
+
end
|
300
|
+
|
301
|
+
`rm -rf rails_app`
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def initialize_with_svn_branches_modules_repository
|
307
|
+
Dir.chdir File.join(root_dir, 'test') do
|
308
|
+
repo_url = with_svn_branches_modules_repository_url
|
309
|
+
|
310
|
+
Dir.chdir 'workdir' do
|
311
|
+
puts `svn co #{[repo_url, "current"].join("/")} modules`
|
312
|
+
raise unless $? == 0
|
313
|
+
Dir.chdir "modules" do
|
314
|
+
if !File.exists? 'modules.txt'
|
315
|
+
open("modules.txt", "w") do |f|
|
316
|
+
f.write "line1 of modules.txt\n"
|
317
|
+
end
|
318
|
+
|
319
|
+
SvnProject.add_all
|
320
|
+
puts `svn commit -m "created modules.txt"`
|
321
|
+
raise unless $? == 0
|
322
|
+
end
|
323
|
+
|
324
|
+
`svn copy #{
|
325
|
+
[repo_url, "current"].join("/")
|
326
|
+
} #{[repo_url, "branches", "branch2"].join("/")
|
327
|
+
} -m "created branch2"`
|
328
|
+
raise unless $? == 0
|
329
|
+
|
330
|
+
puts `svn switch #{
|
331
|
+
[repo_url, "branches", "branch2"].join("/")
|
332
|
+
}`
|
333
|
+
raise unless $? == 0
|
334
|
+
`echo 'line 2 of modules.txt ... this is branch2!' > modules.txt`
|
335
|
+
SvnProject.add_all
|
336
|
+
puts `svn commit -m "changed modules.txt"`
|
337
|
+
raise unless $? == 0
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
|
142
344
|
end
|
143
345
|
end
|
@@ -34,8 +34,30 @@ module Externals
|
|
34
34
|
File.join(root_dir, 'test', 'cleanreps', proj)
|
35
35
|
end
|
36
36
|
|
37
|
+
ext = Ext.new
|
38
|
+
main_project = ext.main_project
|
39
|
+
|
40
|
+
unless !main_project.ignore_contains? "vendor/plugins/engines"
|
41
|
+
raise
|
42
|
+
end
|
37
43
|
#install project with a branch
|
38
44
|
Ext.run "install", File.join(root_dir, 'test', 'cleanreps', 'engines.git'), "-b", "edge"
|
45
|
+
unless main_project.ignore_contains? "vendor/plugins/engines"
|
46
|
+
raise
|
47
|
+
end
|
48
|
+
|
49
|
+
#install fake_rails
|
50
|
+
unless !main_project.ignore_contains? "vendor/rails"
|
51
|
+
raise
|
52
|
+
end
|
53
|
+
Ext.run "install",
|
54
|
+
"--git",
|
55
|
+
File.join(root_dir, 'test', 'cleanreps', 'fake_rails'),
|
56
|
+
"vendor/rails"
|
57
|
+
unless main_project.ignore_contains? "vendor/rails"
|
58
|
+
raise
|
59
|
+
end
|
60
|
+
|
39
61
|
|
40
62
|
GitProject.add_all
|
41
63
|
`git commit -m "created empty rails app with some subprojects"`
|
@@ -115,7 +137,12 @@ module Externals
|
|
115
137
|
ext = Ext.new
|
116
138
|
assert_equal "new_branch", ext.configuration["vendor/plugins/engines"]["branch"]
|
117
139
|
|
118
|
-
|
140
|
+
assert File.exists?(File.join('vendor', 'rails', 'activerecord', 'lib'))
|
141
|
+
#let's uninstall rails
|
142
|
+
Ext.run "uninstall", "-f", "rails"
|
143
|
+
assert !File.exists?(File.join('vendor', 'rails', 'activerecord', 'lib'))
|
144
|
+
|
145
|
+
GitProject.add_all
|
119
146
|
raise unless $? == 0
|
120
147
|
`git commit -m "changed branch on engines subproject"`
|
121
148
|
raise unless $? == 0
|
@@ -131,6 +158,7 @@ module Externals
|
|
131
158
|
Ext.run "up"
|
132
159
|
assert_equal "master", main_project.current_branch
|
133
160
|
assert_equal "edge", engines.current_branch
|
161
|
+
assert File.exists?(File.join('vendor', 'rails', 'activerecord', 'lib'))
|
134
162
|
|
135
163
|
`git checkout new_branch`
|
136
164
|
assert_equal "new_branch", main_project.current_branch
|
@@ -141,7 +169,30 @@ module Externals
|
|
141
169
|
assert_equal "new_branch", engines.current_branch
|
142
170
|
|
143
171
|
`git checkout master`
|
172
|
+
Ext.run "up"
|
144
173
|
assert_equal "master", main_project.current_branch
|
174
|
+
assert_equal "edge", engines.current_branch
|
175
|
+
|
176
|
+
assert main_project.ignore_contains?("vendor/rails")
|
177
|
+
|
178
|
+
#let's test the switch command!
|
179
|
+
Ext.run "switch", "new_branch"
|
180
|
+
assert_equal "new_branch", main_project.current_branch
|
181
|
+
assert_equal "new_branch", engines.current_branch
|
182
|
+
|
183
|
+
assert !main_project.ignore_contains?("vendor/rails")
|
184
|
+
assert File.exists?(File.join('vendor', 'rails', 'activerecord', 'lib'))
|
185
|
+
`rm -rf vendor/rails`
|
186
|
+
assert !File.exists?(File.join('vendor', 'rails', 'activerecord', 'lib'))
|
187
|
+
raise unless $? == 0
|
188
|
+
|
189
|
+
Ext.run "switch", "master"
|
190
|
+
assert_equal "master", main_project.current_branch
|
191
|
+
assert_equal "edge", engines.current_branch
|
192
|
+
|
193
|
+
assert File.exists?(File.join('vendor', 'rails', 'activerecord', 'lib'))
|
194
|
+
|
195
|
+
assert main_project.ignore_contains?("vendor/rails")
|
145
196
|
end
|
146
197
|
|
147
198
|
#now let's check it out again to test "ext checkout -b new_branch"
|