ext 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -1
- data/README +0 -3
- data/bin/ext +0 -0
- data/lib/externals/ext.rb +1 -87
- data/lib/externals/project.rb +15 -6
- data/lib/externals/project_types/rails.rb +5 -17
- data/lib/externals/scms/git_project.rb +1 -8
- data/lib/externals/scms/svn_project.rb +3 -9
- data/test/test_projects.rb +8 -0
- metadata +61 -56
- data/lib/externals/configuration/old_configuration.rb +0 -167
- data/lib/externals/old_project.rb +0 -114
- data/lib/externals/old_scms/old_git_project.rb +0 -116
- data/lib/externals/old_scms/old_svn_project.rb +0 -98
- data/test/test_upgrade_externals_file.rb +0 -86
data/CHANGELOG
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
|
1
|
+
July 19, 2011 Version 1.0.1 released
|
2
|
+
- Fixed a small bug preventing subprojects with a revision associated with them
|
3
|
+
from having their name displayed when updating.
|
4
|
+
|
5
|
+
March 29, 2011 Version 1.0.0 released
|
2
6
|
- Added scm_opts and <scm_name>_opts .externals file options with
|
3
7
|
(_co|_ex|_st|_up) suffixed versions for passing options to the underlying
|
4
8
|
SCM executable.
|
data/README
CHANGED
@@ -82,9 +82,6 @@ update_ignore Adds all paths to subprojects that are
|
|
82
82
|
and so you probably only will run this if you are manually
|
83
83
|
maintaining .externals
|
84
84
|
|
85
|
-
upgrade_externals_fileConverts the old format that stored
|
86
|
-
as [main][svn][git] to [<path1>][<path2>]...
|
87
|
-
|
88
85
|
version Displays the version number of externals and exits.
|
89
86
|
|
90
87
|
|
data/bin/ext
CHANGED
File without changes
|
data/lib/externals/ext.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'externals/project'
|
2
|
-
require 'externals/old_project'
|
3
2
|
require 'externals/configuration/configuration'
|
4
|
-
require 'externals/configuration/old_configuration'
|
5
3
|
require 'optparse'
|
6
4
|
require 'externals/command'
|
7
5
|
require 'externals/extensions/symbol'
|
@@ -10,7 +8,7 @@ module Externals
|
|
10
8
|
#exit status
|
11
9
|
OBSOLETE_EXTERNALS_FILE = 15
|
12
10
|
|
13
|
-
VERSION = '1.0.
|
11
|
+
VERSION = '1.0.1'
|
14
12
|
PROJECT_TYPES_DIRECTORY = File.join(File.dirname(__FILE__), '..', 'externals','project_types')
|
15
13
|
|
16
14
|
# Full commands operate on the main project as well as the externals
|
@@ -70,8 +68,6 @@ module Externals
|
|
70
68
|
main project. This is automatically performed by install,
|
71
69
|
and so you probably only will run this if you are manually
|
72
70
|
maintaining .externals"],
|
73
|
-
[:upgrade_externals_file, "Converts the old format that stored
|
74
|
-
as [main][svn][git] to [<path1>][<path2>]..."],
|
75
71
|
[:version, "Displays the version number of externals and exits."],
|
76
72
|
]
|
77
73
|
|
@@ -92,10 +88,6 @@ module Externals
|
|
92
88
|
require "externals/scms/#{project}" if project =~ /_project.rb$/
|
93
89
|
end
|
94
90
|
|
95
|
-
Dir.entries(File.join(File.dirname(__FILE__), '..', 'externals','old_scms')).each do |project|
|
96
|
-
require "externals/old_scms/#{project}" if project =~ /_project.rb$/
|
97
|
-
end
|
98
|
-
|
99
91
|
Dir.entries(PROJECT_TYPES_DIRECTORY).each do |type|
|
100
92
|
require File.join(PROJECT_TYPES_DIRECTORY, type) if type =~ /\.rb$/
|
101
93
|
end
|
@@ -188,28 +180,10 @@ module Externals
|
|
188
180
|
|
189
181
|
|
190
182
|
Dir.chdir(main_options[:workdir] || ".") do
|
191
|
-
if command == :upgrade_externals_file
|
192
|
-
main_options[:upgrade_externals_file] = true
|
193
|
-
elsif command != :help && command != :version
|
194
|
-
if externals_file_obsolete?
|
195
|
-
puts "your .externals file Appears to be in an obsolete format"
|
196
|
-
puts "Please run 'ext upgrade_externals_file' to migrate it to the new format"
|
197
|
-
exit OBSOLETE_EXTERNALS_FILE
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
183
|
self.new(main_options).send(command, args, sub_options)
|
202
184
|
end
|
203
185
|
end
|
204
186
|
|
205
|
-
def self.externals_file_obsolete?
|
206
|
-
return false if !File.exists?('.externals')
|
207
|
-
|
208
|
-
open('.externals', 'r') do |f|
|
209
|
-
f.read =~ /^\s*\[git\]\s*$|^\s*\[main\]\s*$|^\s*\[svn\]\s*$/
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
187
|
def print_commands(commands)
|
214
188
|
commands.each do |command|
|
215
189
|
puts Command.new(*command)
|
@@ -306,31 +280,6 @@ module Externals
|
|
306
280
|
def initialize options = {}
|
307
281
|
super()
|
308
282
|
|
309
|
-
if options[:upgrade_externals_file]
|
310
|
-
type ||= options[:type]
|
311
|
-
|
312
|
-
|
313
|
-
if type
|
314
|
-
install_project_type type
|
315
|
-
else
|
316
|
-
|
317
|
-
possible_project_types = self.class.project_types.select do |project_type|
|
318
|
-
self.class.project_type_detector(project_type).detected?
|
319
|
-
end
|
320
|
-
|
321
|
-
if possible_project_types.size > 1
|
322
|
-
raise "We found multiple project types that this could be: #{possible_project_types.join(',')}
|
323
|
-
Please use
|
324
|
-
the --type option to tell ext which to use."
|
325
|
-
elsif possible_project_types.empty?
|
326
|
-
install_project_type OldConfiguration::Configuration.new[:main][:type]
|
327
|
-
else
|
328
|
-
install_project_type possible_project_types.first
|
329
|
-
end
|
330
|
-
end
|
331
|
-
return
|
332
|
-
end
|
333
|
-
|
334
283
|
scm = configuration['.']
|
335
284
|
scm = scm['scm'] if scm
|
336
285
|
scm ||= options[:scm]
|
@@ -376,10 +325,6 @@ Please use
|
|
376
325
|
Externals.module_eval("#{scm.to_s.cap_first}Project", __FILE__, __LINE__)
|
377
326
|
end
|
378
327
|
|
379
|
-
def self.old_project_class(scm)
|
380
|
-
Externals.module_eval("Old#{scm.to_s.cap_first}Project", __FILE__, __LINE__)
|
381
|
-
end
|
382
|
-
|
383
328
|
def self.project_classes
|
384
329
|
retval = []
|
385
330
|
registered_scms.each do |scm|
|
@@ -704,29 +649,6 @@ Please use the --type option to tell ext which to use."
|
|
704
649
|
reload_configuration
|
705
650
|
end
|
706
651
|
|
707
|
-
def upgrade_externals_file args, options = {}
|
708
|
-
old = OldConfiguration::Configuration.new
|
709
|
-
|
710
|
-
config = Configuration::Configuration.new_empty
|
711
|
-
|
712
|
-
main = old['main']
|
713
|
-
config.add_empty_section '.'
|
714
|
-
|
715
|
-
config['.'][:scm] = main[:scm]
|
716
|
-
config['.'][:type] = main[:type]
|
717
|
-
|
718
|
-
old.subprojects.each do |subproject|
|
719
|
-
path = subproject.path
|
720
|
-
config.add_empty_section path
|
721
|
-
config[path][:repository] = subproject.repository
|
722
|
-
config[path][:scm] = subproject.scm
|
723
|
-
config[path][:branch] = subproject.branch if subproject.branch
|
724
|
-
end
|
725
|
-
|
726
|
-
config.write('.externals')
|
727
|
-
reload_configuration
|
728
|
-
end
|
729
|
-
|
730
652
|
def version(args, options)
|
731
653
|
puts Externals::VERSION
|
732
654
|
end
|
@@ -736,16 +658,8 @@ Please use the --type option to tell ext which to use."
|
|
736
658
|
end
|
737
659
|
|
738
660
|
def install_project_type name
|
739
|
-
Externals.module_eval("#{name.classify}ProjectType", __FILE__, __LINE__).install
|
740
661
|
self.path_calculator = Externals.module_eval("#{name.classify}ProjectType::DefaultPathCalculator", __FILE__, __LINE__)
|
741
662
|
end
|
742
|
-
#
|
743
|
-
#
|
744
|
-
# def self.determine_project_type path = "."
|
745
|
-
# Dir.chdir path do
|
746
|
-
# raise "not done"
|
747
|
-
# end
|
748
|
-
# end
|
749
663
|
|
750
664
|
protected
|
751
665
|
def do_checkout_or_export repository, path, options, sym
|
data/lib/externals/project.rb
CHANGED
@@ -39,14 +39,19 @@ module Externals
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def self.scm
|
42
|
-
|
42
|
+
if self == Project
|
43
|
+
raise "subclass responsibility"
|
44
|
+
end
|
43
45
|
end
|
46
|
+
|
44
47
|
def scm
|
45
48
|
self.class.scm
|
46
49
|
end
|
50
|
+
|
47
51
|
def self.default_branch
|
48
52
|
raise "subclass responsibility"
|
49
53
|
end
|
54
|
+
|
50
55
|
def default_branch
|
51
56
|
self.class.default_branch
|
52
57
|
end
|
@@ -177,10 +182,15 @@ module Externals
|
|
177
182
|
|
178
183
|
|
179
184
|
def self.inherited child
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
185
|
+
child.class_eval do
|
186
|
+
def self.scm
|
187
|
+
@scm ||= /^([^:]*::)*([^:]+)Project$/.match(name)[2].downcase
|
188
|
+
end
|
189
|
+
|
190
|
+
#create the <scm_name>_opts_co/ex/st/up and <scm_opts>_opts setting
|
191
|
+
#such as svn_opts and svn_opts_co from the main project (stored
|
192
|
+
#in the parrent attribute.)
|
193
|
+
|
184
194
|
raise unless scm && scm != ""
|
185
195
|
|
186
196
|
#first we create global <scm_name>_opts accessors that will apply to all
|
@@ -225,7 +235,6 @@ module Externals
|
|
225
235
|
attributes[name.to_sym] = value
|
226
236
|
end
|
227
237
|
end
|
228
|
-
|
229
238
|
end
|
230
239
|
end
|
231
240
|
|
@@ -1,24 +1,13 @@
|
|
1
1
|
module Externals
|
2
2
|
module RailsProjectType
|
3
|
-
def self.install
|
4
|
-
#obj.send(:extend, Externals::RailsProjectType::Project)
|
5
|
-
Externals::OldProject.send(:include, Externals::RailsProjectType::Project)
|
6
|
-
end
|
7
|
-
|
8
3
|
class DefaultPathCalculator
|
9
4
|
def default_path name
|
10
5
|
if name
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
end
|
17
|
-
|
18
|
-
module Project
|
19
|
-
def default_path
|
20
|
-
if name
|
21
|
-
(name == 'rails') ? File.join("vendor","rails") : File.join("vendor","plugins", name)
|
6
|
+
if name == 'rails'
|
7
|
+
File.join("vendor","rails")
|
8
|
+
else
|
9
|
+
File.join("vendor","plugins", name)
|
10
|
+
end
|
22
11
|
else
|
23
12
|
raise "couldn't figure out project name..."
|
24
13
|
end
|
@@ -26,7 +15,6 @@ module Externals
|
|
26
15
|
end
|
27
16
|
end
|
28
17
|
|
29
|
-
|
30
18
|
class RailsDetector
|
31
19
|
def self.detected?
|
32
20
|
application_path = File.join('config', 'application.rb')
|
@@ -69,10 +69,10 @@ module Externals
|
|
69
69
|
|
70
70
|
def up *args
|
71
71
|
if File.exists? path
|
72
|
+
puts "updating #{path}:"
|
72
73
|
if revision
|
73
74
|
change_to_branch_revision "up"
|
74
75
|
else
|
75
|
-
puts "updating #{path}:"
|
76
76
|
Dir.chdir path do
|
77
77
|
puts `git #{scm_opts_up} pull`
|
78
78
|
end
|
@@ -98,13 +98,6 @@ module Externals
|
|
98
98
|
Integer) {sub_options[:scm] = main_options[:scm] = 'git'}
|
99
99
|
end
|
100
100
|
|
101
|
-
|
102
|
-
def self.scm
|
103
|
-
"git"
|
104
|
-
end
|
105
|
-
|
106
|
-
install_scm_opts_methods
|
107
|
-
|
108
101
|
def self.detected?
|
109
102
|
File.exists? ".git"
|
110
103
|
end
|
@@ -50,10 +50,10 @@ module Externals
|
|
50
50
|
|
51
51
|
def up *args
|
52
52
|
if File.exists? path
|
53
|
+
puts "updating #{path}:"
|
53
54
|
if revision
|
54
55
|
change_to_revision "up"
|
55
56
|
else
|
56
|
-
puts "updating #{path}:"
|
57
57
|
Dir.chdir path do
|
58
58
|
puts `svn #{scm_opts_up} up .`
|
59
59
|
end
|
@@ -73,12 +73,12 @@ module Externals
|
|
73
73
|
def self.scm_path? path
|
74
74
|
return true if path =~ /^svn(\+ssh)?:/
|
75
75
|
|
76
|
-
# Look for http(s)://svn.*/*
|
76
|
+
# Look for http(s)://svn.*/*
|
77
77
|
if path =~ /^https?:\/\/([\w+\-_]+)\.(?:[\w+\-_]+\.)*[\w\-_]+(?:\/|$)/
|
78
78
|
return true if $1.downcase == "svn"
|
79
79
|
end
|
80
80
|
|
81
|
-
# Look for http(s)://*/*svn*/
|
81
|
+
# Look for http(s)://*/*svn*/
|
82
82
|
if path =~ /^https?:\/\/(?:[\w+\-_]+\.?)+\/(\w+)/
|
83
83
|
return true if $1.downcase.include? "svn"
|
84
84
|
end
|
@@ -91,12 +91,6 @@ module Externals
|
|
91
91
|
Integer) {sub_options[:scm] = main_options[:scm] = 'svn'}
|
92
92
|
end
|
93
93
|
|
94
|
-
def self.scm
|
95
|
-
"svn"
|
96
|
-
end
|
97
|
-
|
98
|
-
install_scm_opts_methods
|
99
|
-
|
100
94
|
def self.detected?
|
101
95
|
File.exists? ".svn"
|
102
96
|
end
|
data/test/test_projects.rb
CHANGED
@@ -6,6 +6,14 @@ module Externals
|
|
6
6
|
class TestProjects < TestCase
|
7
7
|
include ExtTestCase
|
8
8
|
|
9
|
+
def test_project_scm
|
10
|
+
assert_equal "svn", SvnProject.scm
|
11
|
+
assert_equal "git", GitProject.scm
|
12
|
+
assert_raise RuntimeError do
|
13
|
+
Project.scm
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
9
17
|
def test_svn_global_opts
|
10
18
|
Dir.chdir File.join(root_dir, 'test') do
|
11
19
|
`rm -rf test_svn_global_opts`
|
metadata
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
4
|
+
hash: 21
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
6
11
|
platform: ruby
|
7
12
|
authors:
|
8
|
-
|
13
|
+
- Miles Georgi
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date: 2011-
|
18
|
+
date: 2011-07-19 00:00:00 -07:00
|
14
19
|
default_executable: ext
|
15
20
|
dependencies: []
|
16
21
|
|
@@ -44,43 +49,38 @@ description: |-
|
|
44
49
|
the main project.
|
45
50
|
email: azimux@gmail.com
|
46
51
|
executables:
|
47
|
-
|
52
|
+
- ext
|
48
53
|
extensions: []
|
49
54
|
|
50
55
|
extra_rdoc_files: []
|
51
56
|
|
52
57
|
files:
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
- test/test_freeze_to_revision.rb
|
80
|
-
- test/test_checkout_with_subprojects_git.rb
|
81
|
-
- test/test_touch_emptydirs.rb
|
82
|
-
- test/test_projects.rb
|
83
|
-
- bin/ext
|
58
|
+
- Rakefile
|
59
|
+
- README
|
60
|
+
- MIT_LICENSE.txt
|
61
|
+
- CHANGELOG
|
62
|
+
- lib/externals/command.rb
|
63
|
+
- lib/externals/configuration/configuration.rb
|
64
|
+
- lib/externals/ext.rb
|
65
|
+
- lib/externals/extensions/string.rb
|
66
|
+
- lib/externals/extensions/symbol.rb
|
67
|
+
- lib/externals/project.rb
|
68
|
+
- lib/externals/project_types/rails.rb
|
69
|
+
- lib/externals/scms/git_project.rb
|
70
|
+
- lib/externals/scms/svn_project.rb
|
71
|
+
- lib/externals/test_case.rb
|
72
|
+
- test/test_checkout_git.rb
|
73
|
+
- test/test_checkout_with_subprojects_git.rb
|
74
|
+
- test/test_checkout_with_subprojects_svn.rb
|
75
|
+
- test/test_freeze_to_revision.rb
|
76
|
+
- test/test_git_project_extract_name.rb
|
77
|
+
- test/test_init_git.rb
|
78
|
+
- test/test_projects.rb
|
79
|
+
- test/test_rails_detection.rb
|
80
|
+
- test/test_string_extensions.rb
|
81
|
+
- test/test_touch_emptydirs.rb
|
82
|
+
- test/test_version.rb
|
83
|
+
- bin/ext
|
84
84
|
has_rdoc: true
|
85
85
|
homepage: http://nopugs.com/ext-tutorial
|
86
86
|
licenses: []
|
@@ -89,36 +89,41 @@ post_install_message:
|
|
89
89
|
rdoc_options: []
|
90
90
|
|
91
91
|
require_paths:
|
92
|
-
|
92
|
+
- lib
|
93
93
|
required_ruby_version: !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
hash: 3
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
version: "0"
|
99
102
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
103
|
none: false
|
101
104
|
requirements:
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
hash: 3
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
version: "0"
|
105
111
|
requirements: []
|
106
112
|
|
107
113
|
rubyforge_project: ext
|
108
|
-
rubygems_version: 1.
|
114
|
+
rubygems_version: 1.3.7
|
109
115
|
signing_key:
|
110
116
|
specification_version: 3
|
111
117
|
summary: Provides an SCM agnostic way to manage subprojects with a workflow similar to the svn:externals feature of subversion. It's particularly useful for rails projects that have some plugins managed by svn and some managed by git.
|
112
118
|
test_files:
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
- test/test_projects.rb
|
119
|
+
- test/test_checkout_git.rb
|
120
|
+
- test/test_checkout_with_subprojects_git.rb
|
121
|
+
- test/test_checkout_with_subprojects_svn.rb
|
122
|
+
- test/test_freeze_to_revision.rb
|
123
|
+
- test/test_git_project_extract_name.rb
|
124
|
+
- test/test_init_git.rb
|
125
|
+
- test/test_projects.rb
|
126
|
+
- test/test_rails_detection.rb
|
127
|
+
- test/test_string_extensions.rb
|
128
|
+
- test/test_touch_emptydirs.rb
|
129
|
+
- test/test_version.rb
|
@@ -1,167 +0,0 @@
|
|
1
|
-
module Externals
|
2
|
-
module OldConfiguration
|
3
|
-
SECTION_TITLE_REGEX = /^\s*\[(\w+)\]\s*$/
|
4
|
-
SECTION_TITLE_REGEX_NO_GROUPS = /^\s*\[(?:\w+)\]\s*$/
|
5
|
-
|
6
|
-
|
7
|
-
class Section
|
8
|
-
attr_accessor :title_string, :body_string, :title, :rows, :scm
|
9
|
-
|
10
|
-
def main?
|
11
|
-
title == 'main'
|
12
|
-
end
|
13
|
-
|
14
|
-
def initialize title_string, body_string, scm = nil
|
15
|
-
self.title_string = title_string
|
16
|
-
self.body_string = body_string
|
17
|
-
self.scm = scm
|
18
|
-
|
19
|
-
self.title = SECTION_TITLE_REGEX.match(title_string)[1]
|
20
|
-
|
21
|
-
self.scm ||= self.title
|
22
|
-
|
23
|
-
raise "Invalid section title: #{title_string}" unless title
|
24
|
-
|
25
|
-
self.rows = body_string.split(/\n/)
|
26
|
-
end
|
27
|
-
|
28
|
-
def setting key
|
29
|
-
if !main?
|
30
|
-
raise "this isn't a section of the configuration that can contain settings"
|
31
|
-
end
|
32
|
-
|
33
|
-
rows.each do |row|
|
34
|
-
if row =~ /\s*(\w+)\s*=\s*([^#\n]*)(?:#[^\n])?$/ && key.to_s == $1
|
35
|
-
return $2.strip
|
36
|
-
end
|
37
|
-
end
|
38
|
-
nil
|
39
|
-
end
|
40
|
-
|
41
|
-
def [] key
|
42
|
-
setting(key)
|
43
|
-
end
|
44
|
-
|
45
|
-
|
46
|
-
def projects
|
47
|
-
return @projects if @projects
|
48
|
-
|
49
|
-
@projects = []
|
50
|
-
|
51
|
-
if main?
|
52
|
-
@projects = [Ext.old_project_class(self['scm']).new(".", :is_main)]
|
53
|
-
else
|
54
|
-
rows.each do |row|
|
55
|
-
if Project.project_line?(row)
|
56
|
-
@projects << Ext.old_project_class(title).new(row)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
@projects
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def add_row(row)
|
64
|
-
rows << row
|
65
|
-
|
66
|
-
self.body_string = body_string.chomp + "\n#{row}\n"
|
67
|
-
clear_caches
|
68
|
-
end
|
69
|
-
|
70
|
-
def clear_caches
|
71
|
-
@projects = nil
|
72
|
-
end
|
73
|
-
|
74
|
-
def to_s
|
75
|
-
"#{title_string}#{body_string}"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
class Configuration
|
80
|
-
attr_accessor :file_string
|
81
|
-
|
82
|
-
def sections
|
83
|
-
@sections ||= []
|
84
|
-
end
|
85
|
-
|
86
|
-
def [] title
|
87
|
-
title = title.to_s
|
88
|
-
sections.detect {|section| section.title == title}
|
89
|
-
end
|
90
|
-
|
91
|
-
def add_empty_section title
|
92
|
-
raise "Section already exists" if self[title]
|
93
|
-
sections << Section.new("\n\n[#{title.to_s}]\n", "")
|
94
|
-
end
|
95
|
-
|
96
|
-
def self.new_empty
|
97
|
-
new nil, true
|
98
|
-
end
|
99
|
-
|
100
|
-
def initialize externals_file = nil, empty = false
|
101
|
-
if empty
|
102
|
-
self.file_string = ''
|
103
|
-
return
|
104
|
-
end
|
105
|
-
|
106
|
-
if !externals_file && File.exists?('.externals')
|
107
|
-
open('.externals', 'r') do |f|
|
108
|
-
externals_file = f.read
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
externals_file ||= ""
|
113
|
-
|
114
|
-
self.file_string = externals_file
|
115
|
-
|
116
|
-
titles = []
|
117
|
-
externals_file.each_line {|line| titles << line if line =~ SECTION_TITLE_REGEX}
|
118
|
-
bodies = externals_file.split SECTION_TITLE_REGEX_NO_GROUPS
|
119
|
-
|
120
|
-
if titles.size > 0 && bodies.size > 0
|
121
|
-
if titles.size + 1 != bodies.size
|
122
|
-
raise "bodies and sections do not match up"
|
123
|
-
end
|
124
|
-
|
125
|
-
bodies = bodies[1..(bodies.size - 1)]
|
126
|
-
|
127
|
-
(0...(bodies.size)).each do |index|
|
128
|
-
sections << Section.new(titles[index], bodies[index])
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
def projects
|
134
|
-
retval = []
|
135
|
-
sections.each do |section|
|
136
|
-
retval += section.projects
|
137
|
-
end
|
138
|
-
|
139
|
-
retval
|
140
|
-
end
|
141
|
-
|
142
|
-
def subprojects
|
143
|
-
retval = []
|
144
|
-
sections.each do |section|
|
145
|
-
retval += section.projects unless section.main?
|
146
|
-
end
|
147
|
-
|
148
|
-
retval
|
149
|
-
end
|
150
|
-
|
151
|
-
def main_project
|
152
|
-
sections.each do |section|
|
153
|
-
return section.projects.first if section.main?
|
154
|
-
end
|
155
|
-
nil
|
156
|
-
end
|
157
|
-
|
158
|
-
def write path = ".externals"
|
159
|
-
open(path, 'w') do |f|
|
160
|
-
sections.each do |section|
|
161
|
-
f.write section.to_s
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
@@ -1,114 +0,0 @@
|
|
1
|
-
module Externals
|
2
|
-
# this regular expression will match a quoted string
|
3
|
-
# it will allow for " to be escaped with "" within the string
|
4
|
-
quoted = '(?:"(?:(?:[^"]*(?:"")?)*)")'
|
5
|
-
|
6
|
-
# this regular expression will match strings of text that are not quoted. They must appear at the start of a line or after a ,
|
7
|
-
# it will also match empty strings like ,,
|
8
|
-
unquoted = '(?:[^"\\s][^\\s$]*)'
|
9
|
-
|
10
|
-
column = "(#{quoted}|#{unquoted})"
|
11
|
-
PROJECT_LINE_REGEX = Regexp.new("^\\s*#{column}(?:\\s+#{column})?\\s*$")
|
12
|
-
|
13
|
-
class OldProject
|
14
|
-
attr_accessor :branch, :repository, :path
|
15
|
-
attr_writer :is_main, :name
|
16
|
-
|
17
|
-
def name
|
18
|
-
@name ||= (extract_name(repository))
|
19
|
-
end
|
20
|
-
|
21
|
-
def main?
|
22
|
-
@is_main
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.scm
|
26
|
-
raise "subclass responsibility"
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
def scm
|
31
|
-
self.class.scm
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
def initialize row_string, is_main = false
|
36
|
-
#raise "Abstract class" if self.class == Project
|
37
|
-
|
38
|
-
#It's the main project
|
39
|
-
self.is_main = is_main || row_string == "."
|
40
|
-
|
41
|
-
if row_string =~ PROJECT_LINE_REGEX
|
42
|
-
repbranch = trim_quotes($1)
|
43
|
-
self.path = trim_quotes($2)
|
44
|
-
|
45
|
-
repbranch = repbranch.strip if repbranch
|
46
|
-
|
47
|
-
if repbranch =~ /^([^\n]*):(\w+)$/
|
48
|
-
self.repository = $1
|
49
|
-
self.branch = $2
|
50
|
-
else
|
51
|
-
self.repository = repbranch
|
52
|
-
end
|
53
|
-
|
54
|
-
self.path = self.path.strip if self.path
|
55
|
-
else
|
56
|
-
raise "poorly formatted .externals entry: #{row_string}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
[:co, :ex].each do |method_name|
|
61
|
-
define_method method_name do |args|
|
62
|
-
raise "subclass responsibility"
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def update_ignore path
|
67
|
-
if !ignore_contains?(path)
|
68
|
-
append_ignore path
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def checkout *args
|
73
|
-
co(*args)
|
74
|
-
end
|
75
|
-
|
76
|
-
def export *args
|
77
|
-
ex(*args)
|
78
|
-
end
|
79
|
-
|
80
|
-
def extract_name repository
|
81
|
-
if repository =~ /\/([\w_-]+)(?:\.git)?$/
|
82
|
-
$1
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def path
|
87
|
-
@path || default_path
|
88
|
-
end
|
89
|
-
|
90
|
-
def parent_path
|
91
|
-
File.dirname path
|
92
|
-
end
|
93
|
-
|
94
|
-
def self.project_line? line
|
95
|
-
#Make sure it's not a comment
|
96
|
-
return false if line =~ /^\s*#/
|
97
|
-
|
98
|
-
line =~ PROJECT_LINE_REGEX
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
protected
|
104
|
-
def trim_quotes value
|
105
|
-
if value
|
106
|
-
if [value[0].chr, value[-1].chr] == ['"', '"']
|
107
|
-
value[1..-2]
|
108
|
-
else
|
109
|
-
value
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,116 +0,0 @@
|
|
1
|
-
module Externals
|
2
|
-
class OldGitProject < OldProject
|
3
|
-
def co *args
|
4
|
-
puts "path is #{path} repository is #{repository}"
|
5
|
-
if path != '.'
|
6
|
-
(rmdircmd = "rmdir #{path}")
|
7
|
-
`#{rmdircmd}` if File.exists?(path)
|
8
|
-
end
|
9
|
-
|
10
|
-
dest = path
|
11
|
-
dest = '' if dest == '.'
|
12
|
-
dest = "\"#{dest}\"" if dest && !dest.empty?
|
13
|
-
|
14
|
-
puts(gitclonecmd = "git clone \"#{repository}\" #{dest}")
|
15
|
-
puts `#{gitclonecmd}`
|
16
|
-
if branch
|
17
|
-
Dir.chdir path do
|
18
|
-
puts `git checkout --track -b #{branch} origin/#{branch}`
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def ex *args
|
24
|
-
if path != '.'
|
25
|
-
(rmdircmd = "rmdir #{path}")
|
26
|
-
`#{rmdircmd}` if File.exists? path
|
27
|
-
end
|
28
|
-
|
29
|
-
dest = path
|
30
|
-
|
31
|
-
dest = '' if dest == '.'
|
32
|
-
|
33
|
-
dest = "\"#{dest}\"" if dest && !dest.empty?
|
34
|
-
|
35
|
-
puts(gitclonecmd = "git clone --depth 1 \"#{repository}\" #{dest}")
|
36
|
-
|
37
|
-
puts `#{gitclonecmd}`
|
38
|
-
if branch
|
39
|
-
puts `cd #{path}; git checkout --track -b #{branch} origin/#{branch}`
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def up *args
|
44
|
-
puts "updating #{path}:"
|
45
|
-
Dir.chdir path do
|
46
|
-
puts `git pull`
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def st *args
|
51
|
-
puts "\nstatus for #{path}:"
|
52
|
-
Dir.chdir path do
|
53
|
-
puts `git status`
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.scm_path? path
|
58
|
-
path =~ /^git:/ || path =~ /.git$/
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.fill_in_opts opts, main_options, sub_options
|
62
|
-
opts.on("--git", "-g", "same as '--scm git' Uses git to checkout/export the main project",
|
63
|
-
Integer) {sub_options[:scm] = main_options[:scm] = 'git'}
|
64
|
-
end
|
65
|
-
|
66
|
-
|
67
|
-
def self.scm
|
68
|
-
"git"
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.detected?
|
72
|
-
File.exists? ".git"
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.add_all
|
76
|
-
puts `git add .`
|
77
|
-
end
|
78
|
-
|
79
|
-
|
80
|
-
protected
|
81
|
-
def ignore_contains? path
|
82
|
-
text = ignore_text
|
83
|
-
text.split(/\n/).detect {|r| r.strip == path.strip}
|
84
|
-
end
|
85
|
-
|
86
|
-
def ignore_text
|
87
|
-
return '' unless File.exists? '.gitignore'
|
88
|
-
retval = ''
|
89
|
-
open('.gitignore') do |f|
|
90
|
-
retval = f.read
|
91
|
-
end
|
92
|
-
retval
|
93
|
-
end
|
94
|
-
|
95
|
-
def append_ignore path
|
96
|
-
rows = ignore_text || ''
|
97
|
-
return if rows.index path.strip
|
98
|
-
|
99
|
-
rows = rows.split(/\n/)
|
100
|
-
rows << path.strip
|
101
|
-
|
102
|
-
rows.delete_if {|row| row =~ /^\s*$/}
|
103
|
-
|
104
|
-
|
105
|
-
open('.gitignore', 'w') do |f|
|
106
|
-
f.write "#{rows.compact.join("\n")}\n"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def extract_name s
|
111
|
-
if s =~ /\/([\w_-]+)(?:\.git)?$/
|
112
|
-
$1
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
module Externals
|
2
|
-
class OldSvnProject < OldProject
|
3
|
-
def co *args
|
4
|
-
(rmdircmd = "rmdir #{path}")
|
5
|
-
|
6
|
-
`#{rmdircmd}` if File.exists? path
|
7
|
-
puts(svncocmd = "svn co #{repository} #{path}")
|
8
|
-
puts `#{svncocmd}`
|
9
|
-
end
|
10
|
-
|
11
|
-
def ex *args
|
12
|
-
(rmdircmd = "rmdir #{path}")
|
13
|
-
|
14
|
-
`#{rmdircmd}` if File.exists? path
|
15
|
-
puts(svncocmd = "svn export #{repository} #{path}")
|
16
|
-
puts `#{svncocmd}`
|
17
|
-
end
|
18
|
-
|
19
|
-
def up *args
|
20
|
-
puts "updating #{path}:"
|
21
|
-
Dir.chdir path do
|
22
|
-
puts `svn up .`
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def st *args
|
27
|
-
puts "\nstatus for #{path}:"
|
28
|
-
Dir.chdir path do
|
29
|
-
puts `svn status`
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.scm_path? path
|
34
|
-
return true if path =~ /^svn(\+ssh)?:/
|
35
|
-
if path =~ /^https?:\/\/([\w+\-_]+)\.(?:[\w+\-_]+\.)*[\w\-_]+(?:\/|$)/
|
36
|
-
return true if $1.downcase == "svn"
|
37
|
-
|
38
|
-
if path =~ /^https?:\/\/(?:[\w_\-]+\.)*[\w\-_]+\/(\w+)\//
|
39
|
-
return true if $1.downcase == "svn"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
false
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.fill_in_opts opts, main_options, sub_options
|
47
|
-
opts.on("--svn", "--subversion","-s", "same as '--scm svn' Uses subversion to checkout/export the main project",
|
48
|
-
Integer) {sub_options[:scm] = main_options[:scm] = 'svn'}
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.scm
|
52
|
-
"svn"
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.detected?
|
56
|
-
File.exists? ".svn"
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.add_all
|
60
|
-
status = `svn st`
|
61
|
-
|
62
|
-
status.split("\n").grep(/^\?/).each do |to_add|
|
63
|
-
puts `svn add #{to_add.gsub(/^\?\s*/,"")}`
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
|
68
|
-
protected
|
69
|
-
def ignore_contains? path
|
70
|
-
ignore_text(path) =~ Regexp.new("^\\s*#{File.basename(path)}\\s*$")
|
71
|
-
end
|
72
|
-
|
73
|
-
def append_ignore path
|
74
|
-
parent = File.dirname(path)
|
75
|
-
child = File.basename(path)
|
76
|
-
|
77
|
-
rows = ignore_text(path).split(/\n/)
|
78
|
-
|
79
|
-
return if rows.detect {|row| row.strip == child.strip}
|
80
|
-
|
81
|
-
rows << child.strip
|
82
|
-
|
83
|
-
rows.delete_if {|row| row =~ /^\s*$/}
|
84
|
-
|
85
|
-
Dir.chdir(parent) do
|
86
|
-
puts `svn propset svn:ignore "#{rows.compact.join("\n")}\n" .`
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def ignore_text(path)
|
91
|
-
ignore_text = ''
|
92
|
-
Dir.chdir File.dirname(path) do
|
93
|
-
puts(ignore_text = `svn propget svn:ignore`)
|
94
|
-
end
|
95
|
-
ignore_text
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
@@ -1,86 +0,0 @@
|
|
1
|
-
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib') if $0 == __FILE__
|
2
|
-
require 'externals/test_case'
|
3
|
-
require 'externals/ext'
|
4
|
-
|
5
|
-
module Externals
|
6
|
-
class TestUpgradeExternalsFile < TestCase
|
7
|
-
include ExtTestCase
|
8
|
-
|
9
|
-
def test_upgrade
|
10
|
-
Dir.chdir File.join(root_dir, 'test') do
|
11
|
-
`rm -rf test_upgrade`
|
12
|
-
`mkdir test_upgrade`
|
13
|
-
|
14
|
-
|
15
|
-
Dir.chdir 'test_upgrade' do
|
16
|
-
open '.externals', 'w' do |f|
|
17
|
-
f.write "[main]
|
18
|
-
|
19
|
-
scm = git
|
20
|
-
type = rails
|
21
|
-
[git]
|
22
|
-
|
23
|
-
git://github.com/rails/rails.git
|
24
|
-
git://github.com/rails/acts_as_list.git:edge
|
25
|
-
[svn]
|
26
|
-
|
27
|
-
svn://rubyforge.org/var/svn/redhillonrails/trunk/vendor/plugins/foreign_key_migrations
|
28
|
-
svn://rubyforge.org/var/svn/redhillonrails/trunk/vendor/plugins/redhillonrails_core"
|
29
|
-
end
|
30
|
-
|
31
|
-
assert Ext.externals_file_obsolete?
|
32
|
-
|
33
|
-
Ext.run "upgrade_externals_file"
|
34
|
-
assert !Ext.externals_file_obsolete?
|
35
|
-
|
36
|
-
new_text = nil
|
37
|
-
open '.externals', 'r' do |f|
|
38
|
-
new_text = f.read
|
39
|
-
end
|
40
|
-
puts new_text
|
41
|
-
|
42
|
-
config1 = Configuration::Configuration.new(new_text)
|
43
|
-
|
44
|
-
config2 = Configuration::Configuration.new("[.]
|
45
|
-
scm = git
|
46
|
-
type = rails
|
47
|
-
|
48
|
-
[vendor/rails]
|
49
|
-
scm = git
|
50
|
-
repository = git://github.com/rails/rails.git
|
51
|
-
|
52
|
-
[vendor/plugins/acts_as_list]
|
53
|
-
scm = git
|
54
|
-
repository = git://github.com/rails/acts_as_list.git
|
55
|
-
branch = edge
|
56
|
-
|
57
|
-
[vendor/plugins/foreign_key_migrations]
|
58
|
-
scm = svn
|
59
|
-
repository = svn://rubyforge.org/var/svn/redhillonrails/trunk/vendor/plugins/foreign_key_migrations
|
60
|
-
|
61
|
-
[vendor/plugins/redhillonrails_core]
|
62
|
-
scm = svn
|
63
|
-
repository = svn://rubyforge.org/var/svn/redhillonrails/trunk/vendor/plugins/redhillonrails_core")
|
64
|
-
|
65
|
-
|
66
|
-
assert(config1.sections.size == 5)
|
67
|
-
|
68
|
-
[[config1, config2], [config2,config1]].each do |array|
|
69
|
-
c1 = array[0]
|
70
|
-
c2 = array[1]
|
71
|
-
|
72
|
-
c1.sections.each do |section|
|
73
|
-
s2 = c2[section.title]
|
74
|
-
assert s2
|
75
|
-
section.attributes.each_pair do |key,value|
|
76
|
-
assert s2[key] == value
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
`rm -rf test_upgrade`
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|