ext 1.0.0 → 1.0.1
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 -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
|