ext 1.1.3 → 2.0.0

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/lib/externals/ext.rb CHANGED
@@ -4,59 +4,55 @@ require 'optparse'
4
4
  require 'externals/command'
5
5
  require 'fileutils'
6
6
 
7
+ require_relative "../../version"
8
+
7
9
  Dir.entries(File.join(File.dirname(__FILE__), 'extensions')).each do |extension|
8
10
  require "externals/extensions/#{extension}" if extension =~ /.rb$/
9
11
  end
10
12
 
11
13
  module Externals
12
- VERSION = '1.1.3'
13
- PROJECT_TYPES_DIRECTORY = File.join(File.dirname(__FILE__), '..', 'externals','project_types')
14
-
15
14
  # Full commands operate on the main project as well as the externals
16
15
  # short commands only operate on the externals
17
16
  # Main commands only operate on the main project
18
17
  FULL_COMMANDS_HASH = [
19
18
  [:checkout, "ext checkout <repository>",
20
- %{Checks out <repository>, and checks out any subprojects
19
+ %{Checks out <repository>, and checks out any subprojects
21
20
  registered in <repository>'s .externals file.}],
22
21
  [:export, "ext export <repository>",
23
- %{Like checkout except this command fetches as little
22
+ %{Like checkout except this command fetches as little
24
23
  history as possible.}],
25
24
  [:status, "ext status",
26
- %{Prints out the status of the main project, followed by
25
+ %{Prints out the status of the main project, followed by
27
26
  the status of each subproject.}],
28
27
  [:update, "ext update",
29
- %{Brings the main project, and all subprojects, up to the
28
+ %{Brings the main project, and all subprojects, up to the
30
29
  latest version.}]
31
- ]
30
+ ].freeze
32
31
  SHORT_COMMANDS_HASH = [
33
32
  [:co, "Like checkout, but skips the main project and
34
33
  only checks out subprojects."],
35
34
  [:ex, "Like export, but skips the main project."],
36
35
  [:st, "Like status, but skips the main project."],
37
36
  [:up, "Like update, but skips the main project."]
38
- ]
37
+ ].freeze
39
38
  MAIN_COMMANDS_HASH = [
40
39
  [:freeze, "ext freeze <subproject> [REVISION]",
41
- %{Locks a subproject into a specific revision/branch. If no
40
+ %{Locks a subproject into a specific revision/branch. If no
42
41
  revision is supplied, the current revision/branch of the
43
42
  project will be used. You can specify the subproject by name
44
43
  or path.}],
45
44
  [:help, "You probably just ran this command just now."],
46
45
  [:init, "Creates a .externals file containing only [main]
47
- It will try to determine the SCM used by the main project,
48
- as well as the project type. You don't have to specify
49
- a project type if you don't want to or if your project type
50
- isn't supported. It just means that when using 'install'
51
- that you'll want to specify the path."],
52
- [:install, "ext install <repository> [-b <branch>] [path]",
53
- "Registers <repository> in .externals under the appropriate
54
- SCM. Checks out the project, and also adds it to the ignore
46
+ It will try to determine the SCM used by the main project."],
47
+ [:install, "ext install <repository> [-b <branch>] <path>",
48
+ "Registers <repository> in .externals under the appropriate
49
+ SCM. Checks out the subproject at given path,
50
+ and also adds it to the ignore
55
51
  feature offered by the SCM of the main project. If the SCM
56
52
  type is not obvious from the repository URL, use the --scm,
57
53
  --git, or --svn flags."],
58
54
  [:switch, "ext switch <branch_name>",
59
- "Changes to the named branch <branch_name> and updates any
55
+ "Changes to the named branch <branch_name> and updates any
60
56
  subprojects and applies any changes that have been made to the
61
57
  .externals file."],
62
58
  [:touch_emptydirs, "Recurses through all directories from the
@@ -64,10 +60,10 @@ module Externals
64
60
  comes across. Useful for dealing with SCMs that refuse to
65
61
  track empty directories (such as git, for example)"],
66
62
  [:unfreeze, "ext unfreeze <subproject>",
67
- %{Unfreezes a previously frozen subproject. You can specify
63
+ %{Unfreezes a previously frozen subproject. You can specify
68
64
  the subproject by name or path.}],
69
65
  [:uninstall, "ext uninstall [-f|--force_removal] <project>",
70
- "Removes a subproject from being tracked by ext. If you
66
+ "Removes a subproject from being tracked by ext. If you
71
67
  want the files associated with this subproject deleted as well
72
68
  (if, for example, you wish to reinstall it from a different
73
69
  repository) then you can use the -f option to remove the files."],
@@ -77,11 +73,10 @@ module Externals
77
73
  and so you probably only will run this if you are manually
78
74
  maintaining .externals"],
79
75
  [:version, "Displays the version number of externals and exits."],
80
- ]
81
-
76
+ ].freeze
82
77
 
83
78
  FULL_COMMANDS = FULL_COMMANDS_HASH.map(&:first)
84
- SHORT_COMMANDS = SHORT_COMMANDS_HASH.map(&:first)
79
+ SHORT_COMMANDS = SHORT_COMMANDS_HASH.map(&:first)
85
80
  MAIN_COMMANDS = MAIN_COMMANDS_HASH.map(&:first)
86
81
 
87
82
  COMMANDS = FULL_COMMANDS + SHORT_COMMANDS + MAIN_COMMANDS
@@ -89,40 +84,14 @@ module Externals
89
84
  COULD_NOT_DETERMINE_SCM = 1
90
85
  NO_EXTERNALS_FILE = 2
91
86
 
92
- Dir.entries(File.join(File.dirname(__FILE__), '..', 'externals','scms')).each do |project|
87
+ Dir.entries(File.join(File.dirname(__FILE__), '..', 'externals', 'scms')).each do |project|
93
88
  require "externals/scms/#{project}" if project =~ /_project.rb$/
94
89
  end
95
90
 
96
- Dir.entries(PROJECT_TYPES_DIRECTORY).each do |type|
97
- require File.join(PROJECT_TYPES_DIRECTORY, type) if type =~ /\.rb$/
98
- end
99
-
100
91
  class Ext
101
92
  include FileUtils
102
93
  extend FileUtils
103
94
 
104
- attr_accessor :path_calculator
105
-
106
- def self.project_types
107
- types = Dir.entries(PROJECT_TYPES_DIRECTORY).select do |file|
108
- file =~ /\.rb$/
109
- end
110
-
111
- types.map do |type|
112
- /^(.*)\.rb$/.match(type)[1]
113
- end
114
- end
115
-
116
- def self.project_type_files
117
- project_types.map do |project_type|
118
- "#{File.join(PROJECT_TYPES_DIRECTORY, project_type)}.rb"
119
- end
120
- end
121
-
122
- project_type_files.each do |file|
123
- require file
124
- end
125
-
126
95
  def self.new_opts main_options, sub_options
127
96
  opts = OptionParser.new(
128
97
  "ext [OPTIONS] <command> [repository] [-b <branch>] [path]"
@@ -133,37 +102,35 @@ module Externals
133
102
 
134
103
  project_classes.each do |project_class|
135
104
  project_class.fill_in_opts(opts, main_options, sub_options,
136
- :summary_width => summary_width)
105
+ :summary_width => summary_width)
137
106
  end
138
107
 
139
- opts.on("--type TYPE", "-t TYPE",
140
- String,
141
- *"The type of project the main project is.
142
- For example, 'rails'.".lines_by_width(summary_width)
143
- ) {|type| sub_options[:type] = main_options[:type] = type}
144
108
  opts.on("--scm SCM", "-s SCM",
145
- String,
146
- *"The SCM used to manage the main project. For example, '--scm svn'.".lines_by_width(summary_width)
109
+ String,
110
+ *"The SCM used to manage the main project. For example, '--scm svn'.".lines_by_width(summary_width)
147
111
  ) {|scm| sub_options[:scm] = main_options[:scm] = scm}
148
112
  opts.on("--branch BRANCH", "-b BRANCH",
149
- String,
150
- *"The branch you want the
113
+ String,
114
+ *"The branch you want the
151
115
  subproject to checkout when doing 'ext install'".lines_by_width(summary_width)
152
116
  ) {|branch| sub_options[:branch] = main_options[:branch] = branch}
153
117
  opts.on("--revision REVISION", "-r REVISION",
154
- String,
155
- *"The revision you want the
118
+ String,
119
+ *"The revision you want the
156
120
  subproject to checkout when doing 'ext install'".lines_by_width(summary_width)
157
121
  ) {|revision| sub_options[:revision] = main_options[:revision] = revision}
158
122
  opts.on("--force_removal", "-f",
159
- String,
160
- *"When doing an uninstall of a subproject,
123
+ String,
124
+ *"When doing an uninstall of a subproject,
161
125
  remove it's files and subfolders, too.".lines_by_width(summary_width)
162
- ) {|branch| sub_options[:force_removal] = true}
163
- opts.on("--workdir DIR", "-w DIR", String, *"The working directory to execute commands from. Use this if for some reason you
126
+ ) { sub_options[:force_removal] = true }
127
+ opts.on(
128
+ "--workdir DIR", "-w DIR", String,
129
+ *"The working directory to execute commands from. Use this if for some reason you
164
130
  cannot execute ext from the main project's directory (or if it's just inconvenient, such as in a script
165
131
  or in a Capistrano task)".lines_by_width(summary_width)) {|dir|
166
132
  raise "No such directory: #{dir}" unless File.exist?(dir) && File.directory?(dir)
133
+
167
134
  main_options[:workdir] = dir
168
135
  }
169
136
  opts.on(
@@ -187,7 +154,7 @@ module Externals
187
154
 
188
155
  unless args.nil? || args.empty?
189
156
  command = args[0]
190
- args = args[1..(args.size - 1)] || []
157
+ args = args[1..] || []
191
158
  end
192
159
 
193
160
  command &&= command.to_sym
@@ -196,20 +163,23 @@ module Externals
196
163
  command = :version if main_options[:version]
197
164
 
198
165
  if !command || command.to_s == ''
166
+ # :nocov:
199
167
  puts "hey... you didn't tell me what you want to do."
200
168
  puts "Try 'ext help' for a list of commands"
201
- exit
169
+ exit 1
170
+ # :nocov:
202
171
  end
203
172
 
204
173
  unless COMMANDS.index command
174
+ # :nocov:
205
175
  puts "unknown command: #{command}"
206
176
  puts "for a list of commands try 'ext help'"
207
- exit
177
+ exit 1
178
+ # :nocov:
208
179
  end
209
180
 
210
-
211
181
  Dir.chdir(main_options[:workdir] || ".") do
212
- self.new(main_options).send(command, args, sub_options)
182
+ new(main_options).send(command, args, sub_options)
213
183
  end
214
184
  end
215
185
 
@@ -220,9 +190,9 @@ module Externals
220
190
  puts
221
191
  end
222
192
 
223
- def help(args, options)
193
+ def help(_args, _options)
224
194
  puts "There's a tutorial available at http://nopugs.com/ext-tutorial\n\n"
225
- puts "#{self.class.new_opts({},{}).to_s}\n\n"
195
+ puts "#{self.class.new_opts({}, {})}\n\n"
226
196
 
227
197
  puts "\nCommands that apply to the main project or the .externals file:"
228
198
  puts "#{MAIN_COMMANDS.join(', ')}\n\n"
@@ -240,6 +210,7 @@ module Externals
240
210
  @registered_scms = nil
241
211
  def self.registered_scms
242
212
  return @registered_scms if @registered_scms
213
+
243
214
  @registered_scms ||= []
244
215
 
245
216
  scmdir = File.join(File.dirname(__FILE__), 'scms')
@@ -255,9 +226,10 @@ module Externals
255
226
 
256
227
  def projects
257
228
  return @projects if @projects
229
+
258
230
  @projects = []
259
231
  configuration.sections.each do |section|
260
- @projects << Ext.project_class(section[:scm]||infer_scm(section[:repository])).new(
232
+ @projects << Ext.project_class(section[:scm] || infer_scm(section[:repository])).new(
261
233
  section.attributes.merge(:path => section.title))
262
234
  end
263
235
  #let's set the parents of these projects
@@ -272,11 +244,14 @@ module Externals
272
244
  project ||= subprojects.detect do |p|
273
245
  File.split(p.path).last.strip == name
274
246
  end
275
- project ||= subprojects.detect do |p|
247
+ project || subprojects.detect do |p|
248
+ # TODO: test (or delete) this code path!
249
+ # :nocov:
276
250
  p.name == name
251
+ # :nocov:
277
252
  end
278
253
  end
279
- alias :subproject :subproject_by_name_or_path
254
+ alias subproject subproject_by_name_or_path
280
255
 
281
256
  def subprojects
282
257
  s = []
@@ -287,7 +262,7 @@ module Externals
287
262
  end
288
263
 
289
264
  def main_project
290
- projects.detect {|p| p.main_project?}
265
+ projects.detect(&:main_project?)
291
266
  end
292
267
 
293
268
  def configuration
@@ -316,43 +291,17 @@ module Externals
316
291
 
317
292
  scm = configuration['.']
318
293
  scm = scm['scm'] if scm
319
- scm ||= options[:scm]
320
-
321
- type = configuration['.']
322
- type = type['type'] if type
323
-
324
- type ||= options[:type]
325
-
326
- if type
327
- install_project_type type
328
- else
329
- possible_project_types = self.class.project_types.select do |project_type|
330
- self.class.project_type_detector(project_type).detected?
331
- end
332
-
333
- if possible_project_types.size > 1
334
- raise "We found multiple project types that this could be: #{possible_project_types.join(',')}
335
- Please use
336
- the --type option to tell ext which to use."
337
- else
338
- possible_project_types.each do |project_type|
339
- install_project_type project_type
340
- end
341
- end
342
- end
294
+ scm || options[:scm]
343
295
  end
344
296
 
345
297
  def self.project_class(scm)
346
- Externals.module_eval("#{scm.to_s.cap_first}Project", __FILE__, __LINE__)
298
+ Externals.const_get("#{scm.to_s.cap_first}Project")
347
299
  end
348
300
 
349
301
  def self.project_classes
350
- retval = []
351
- registered_scms.each do |scm|
352
- retval << project_class(scm)
302
+ registered_scms.map do |scm|
303
+ project_class(scm)
353
304
  end
354
-
355
- retval
356
305
  end
357
306
 
358
307
  SHORT_COMMANDS.each do |command_name|
@@ -368,16 +317,18 @@ Please use
368
317
  p.name == project_name_or_path || p.path == project_name_or_path
369
318
  end
370
319
 
320
+ # :nocov:
371
321
  raise "no such project" unless project
322
+ # :nocov:
372
323
 
373
324
  project.send command_name, args, options
374
325
  else
375
- subprojects.each {|p| p.send(*([command_name, args, options].flatten))}
326
+ subprojects.each {|p| p.send(*[command_name, args, options].flatten)}
376
327
  end
377
328
  end
378
329
  end
379
330
 
380
- def freeze args, options
331
+ def freeze args, _options
381
332
  project = subproject_by_name_or_path(args[0])
382
333
 
383
334
  raise "No such project named #{args[0]}" unless project
@@ -391,7 +342,10 @@ Please use
391
342
  if branch
392
343
  section[:branch] = branch
393
344
  else
345
+ # TODO: test (or delete) this code path!
346
+ # :nocov:
394
347
  section.rm_setting :branch
348
+ # :nocov:
395
349
  end
396
350
  end
397
351
  section[:revision] = revision
@@ -401,7 +355,7 @@ Please use
401
355
  subproject_by_name_or_path(args[0]).up
402
356
  end
403
357
 
404
- def unfreeze args, options
358
+ def unfreeze args, _options
405
359
  project = subproject_by_name_or_path(args[0])
406
360
 
407
361
  raise "No such project named #{args[0]}" unless project
@@ -409,8 +363,10 @@ Please use
409
363
  section = configuration[project.path]
410
364
 
411
365
  unless section[:revision]
366
+ # :nocov:
412
367
  puts "Uhh... #{project.name} wasn't frozen, so I can't unfreeze it."
413
- exit
368
+ exit 1
369
+ # :nocov:
414
370
  end
415
371
 
416
372
  section.rm_setting :revision
@@ -422,8 +378,10 @@ Please use
422
378
 
423
379
  def install args, options
424
380
  if !File.exist?('.externals')
425
- STDERR.puts "This project does not appear to be managed by externals. Try 'ext init' first"
381
+ # :nocov:
382
+ warn "This project does not appear to be managed by externals. Try 'ext init' first"
426
383
  exit NO_EXTERNALS_FILE
384
+ # :nocov:
427
385
  end
428
386
  repository = args[0]
429
387
  path = args[1]
@@ -435,15 +393,17 @@ Please use
435
393
  scm ||= infer_scm(repository)
436
394
 
437
395
  unless scm
438
- STDERR.puts "Unable to determine SCM from the repository name.
396
+ # :nocov:
397
+ warn "Unable to determine SCM from the repository name.
439
398
  You need to either specify the scm used to manage the subproject
440
399
  that you are installing. Use an option to specify it
441
400
  (such as --git or --svn)"
442
401
  exit COULD_NOT_DETERMINE_SCM
402
+ # :nocov:
443
403
  end
444
404
 
445
405
  project = self.class.project_class(scm).new(:repository => repository,
446
- :path => path || path_calculator.new, :scm => scm)
406
+ :path => path, :scm => scm)
447
407
  path = project.path
448
408
 
449
409
  raise "no path" unless path
@@ -466,7 +426,9 @@ that you are installing. Use an option to specify it
466
426
 
467
427
  def uninstall args, options
468
428
  unless File.exist?('.externals')
429
+ # :nocov:
469
430
  raise "Hmm... there's no .externals file in this directory."
431
+ # :nocov:
470
432
  end
471
433
 
472
434
  project = subproject_by_name_or_path(args[0])
@@ -475,7 +437,6 @@ that you are installing. Use an option to specify it
475
437
 
476
438
  main_project.drop_from_ignore project.path
477
439
 
478
-
479
440
  configuration.remove_section(project.path)
480
441
  configuration.write '.externals'
481
442
  reload_configuration
@@ -487,15 +448,18 @@ that you are installing. Use an option to specify it
487
448
  end
488
449
  end
489
450
 
490
- def update_ignore args, options
451
+ def update_ignore _args, options
491
452
  scm = configuration['.']
492
453
  scm = scm['scm'] if scm
493
454
 
494
455
  scm ||= options[:scm]
495
456
 
496
457
  unless scm
497
- raise "You need to either specify the scm as the first line in .externals (for example, scm = git), or use an option to specify it
458
+ # :nocov:
459
+ raise "You need to either specify the scm as the first line in .externals (for example, scm = git), " \
460
+ "or use an option to specify it
498
461
  (such as --git or --svn)"
462
+ # :nocov:
499
463
  end
500
464
 
501
465
  project = self.class.project_class(scm).new(:path => ".")
@@ -507,10 +471,10 @@ that you are installing. Use an option to specify it
507
471
  end
508
472
  end
509
473
 
510
- def touch_emptydirs args, options
474
+ def touch_emptydirs _args, _options
511
475
  require 'find'
512
476
 
513
- excludes = ['.','..','.svn', '.git']
477
+ excludes = ['.', '..', '.svn', '.git']
514
478
 
515
479
  excludes.dup.each do |exclude|
516
480
  excludes << "./#{exclude}"
@@ -522,23 +486,26 @@ that you are installing. Use an option to specify it
522
486
  if File.directory?(f)
523
487
  excluded = false
524
488
  File.split(f).each do |part|
525
- exclude ||= excludes.index(part)
489
+ excluded ||= excludes.index(part)
526
490
  end
527
491
 
528
- if !excluded && ((Dir.entries(f) - excludes).size == 0)
492
+ if !excluded && (Dir.entries(f) - excludes).empty?
529
493
  paths << f
530
494
  end
531
495
  end
532
496
  end
533
497
 
534
498
  paths.each do |p|
535
- open(File.join(p,".emptydir"), "w").close
499
+ # TODO: is there not an easier way to touch a file??
500
+ # rubocop:disable Style/FileOpen
501
+ f = File.open(File.join(p, ".emptydir"), "w")
502
+ # rubocop:enable Style/FileOpen
503
+ ensure
504
+ f.close
536
505
  end
537
-
538
506
  end
539
507
 
540
-
541
- def status args, options
508
+ def status _args, options
542
509
  options ||= {}
543
510
  scm = options[:scm]
544
511
 
@@ -548,24 +515,27 @@ that you are installing. Use an option to specify it
548
515
  end
549
516
 
550
517
  if !scm
551
- possible_project_classes = self.class.project_classes.select do |project_class|
552
- project_class.detected?
553
- end
518
+ # TODO: test (or delete) this code path!
519
+ # :nocov:
520
+ possible_project_classes = self.class.project_classes.select(&:detected?)
554
521
 
555
- raise "Could not determine this projects scm" if possible_project_classes.empty?
522
+ raise "Could not determine this projects scm" if possible_project_classes.empty?
556
523
  if possible_project_classes.size > 1
557
524
  raise "This project appears to be managed by multiple SCMs: #{
558
- possible_project_classes.map(&:to_s).join(',')}
525
+ possible_project_classes.join(',')}
559
526
  Please explicitly declare the SCM (by using --git or --svn, or,
560
527
  by creating the .externals file manually"
561
528
  end
562
529
 
563
530
  scm = possible_project_classes.first.scm
531
+ # :nocov:
564
532
  end
565
533
 
566
534
  unless scm
535
+ # :nocov:
567
536
  raise "You need to either specify the scm as the first line in .externals, or use an option to specify it
568
537
  (such as --git or --svn)"
538
+ # :nocov:
569
539
  end
570
540
 
571
541
  project = main_project
@@ -587,24 +557,27 @@ by creating the .externals file manually"
587
557
  end
588
558
 
589
559
  if !scm
590
- possible_project_classes = self.class.project_classes.select do |project_class|
591
- project_class.detected?
592
- end
560
+ # TODO: test (or delete) this code path!
561
+ # :nocov:
562
+ possible_project_classes = self.class.project_classes.select(&:detected?)
593
563
 
594
- raise "Could not determine this projects scm" if possible_project_classes.empty?
564
+ raise "Could not determine this projects scm" if possible_project_classes.empty?
595
565
  if possible_project_classes.size > 1
596
566
  raise "This project appears to be managed by multiple SCMs: #{
597
- possible_project_classes.map(&:to_s).join(',')}
567
+ possible_project_classes.join(',')}
598
568
  Please explicitly declare the SCM (by using --git or --svn, or,
599
569
  by creating the .externals file manually"
600
570
  end
601
571
 
602
572
  scm = possible_project_classes.first.scm
573
+ # :nocov:
603
574
  end
604
575
 
605
576
  unless scm
577
+ # :nocov:
606
578
  raise "You need to either specify the scm as the first line in .externals, or use an option to specify it
607
579
  (such as --git or --svn)"
580
+ # :nocov:
608
581
  end
609
582
 
610
583
  old_config = configuration
@@ -639,7 +612,7 @@ commands below if you actually wish to delete them."
639
612
  end
640
613
  end
641
614
 
642
- def update args, options
615
+ def update _args, options
643
616
  options ||= {}
644
617
  scm = options[:scm]
645
618
 
@@ -649,8 +622,10 @@ commands below if you actually wish to delete them."
649
622
  end
650
623
 
651
624
  unless scm
625
+ # :nocov:
652
626
  raise "You need to either specify the scm as the first line in .externals, or use an option to specify it
653
627
  (such as --git or --svn)"
628
+ # :nocov:
654
629
  end
655
630
 
656
631
  project = main_project
@@ -673,7 +648,7 @@ commands below if you actually wish to delete them."
673
648
  end
674
649
 
675
650
  Dir.chdir path do
676
- self.class.new({}).co [], {} #args, options
651
+ self.class.new({}).co [], {}
677
652
  end
678
653
  end
679
654
 
@@ -686,7 +661,10 @@ commands below if you actually wish to delete them."
686
661
  main_project = do_checkout_or_export repository, path, options, :export
687
662
 
688
663
  if path == "."
664
+ # TODO: test (or delete) this code path!
665
+ # :nocov:
689
666
  path = main_project.name
667
+ # :nocov:
690
668
  end
691
669
 
692
670
  Dir.chdir path do
@@ -695,42 +673,27 @@ commands below if you actually wish to delete them."
695
673
  end
696
674
 
697
675
  def init args, options = {}
676
+ # :nocov:
698
677
  raise ".externals already exists" if File.exist?('.externals')
678
+ # :nocov:
699
679
 
700
680
  scm = options[:scm]
701
- type = options[:type]
702
681
 
703
682
  if !scm
704
- possible_project_classes = self.class.project_classes.select do |project_class|
705
- project_class.detected?
706
- end
683
+ possible_project_classes = self.class.project_classes.select(&:detected?)
707
684
 
708
- raise "Could not determine this project's scm" if possible_project_classes.empty?
685
+ raise "Could not determine this project's scm" if possible_project_classes.empty?
709
686
  if possible_project_classes.size > 1
687
+ # :nocov:
710
688
  raise "This project appears to be managed by multiple SCMs: #{
711
- possible_project_classes.map(&:to_s).join(',')}
689
+ possible_project_classes.join(',')}
712
690
  Please explicitly declare the SCM (using --git or --svn, or, by creating .externals manually"
691
+ # :nocov:
713
692
  end
714
693
 
715
694
  scm = possible_project_classes.first.scm
716
695
  end
717
696
 
718
- if !type
719
- possible_project_types = self.class.project_types.select do |project_type|
720
- self.class.project_type_detector(project_type).detected?
721
- end
722
-
723
- if possible_project_types.size > 1
724
- raise "We found multiple project types that this could be: #{possible_project_types.join(',')}
725
- Please use the --type option to tell ext which to use."
726
- elsif possible_project_types.size == 0
727
- puts "WARNING: We could not automatically determine the project type.
728
- Be sure to specify paths when adding subprojects to your .externals file"
729
- else
730
- type = possible_project_types.first
731
- end
732
- end
733
-
734
697
  config = Configuration::Configuration.new_empty
735
698
  raise ".externals already exists" if File.exist?('.externals')
736
699
 
@@ -744,33 +707,30 @@ Please use the --type option to tell ext which to use."
744
707
  options[:branch]
745
708
  )
746
709
  elsif args[0]
710
+ # TODO: test (or delete) this code path!
711
+ # :nocov:
747
712
  config['.'][:repository] = args[0].strip
713
+ # :nocov:
748
714
  end
749
715
  end
750
716
 
751
717
  config['.'][:scm] = scm
752
- config['.'][:type] = type if type
753
718
 
754
719
  config.write '.externals'
755
720
  reload_configuration
756
721
  end
757
722
 
758
- def version(args, options)
723
+ def version(_args, _options)
759
724
  puts Externals::VERSION
760
725
  end
761
726
 
762
- def self.project_type_detector name
763
- Externals.module_eval("#{name.classify}Detector", __FILE__, __LINE__)
764
- end
765
-
766
- def install_project_type name
767
- self.path_calculator = Externals.module_eval("#{name.classify}ProjectType::DefaultPathCalculator", __FILE__, __LINE__)
768
- end
769
-
770
727
  protected
728
+
771
729
  def do_checkout_or_export repository, path, options, sym
772
730
  if File.exist?('.externals')
731
+ # :nocov:
773
732
  raise "seems main project is already checked out here?"
733
+ # :nocov:
774
734
  else
775
735
  #We appear to be attempting to checkout/export a main project
776
736
  scm = options[:scm]
@@ -778,13 +738,18 @@ Please use the --type option to tell ext which to use."
778
738
  scm ||= infer_scm(repository)
779
739
 
780
740
  if !scm
741
+ # TODO: test (or delete) this code path!
742
+ # :nocov:
781
743
  scm ||= configuration['main']
782
744
  scm &&= scm['scm']
745
+ # :nocov:
783
746
  end
784
747
 
785
748
  unless scm
749
+ # :nocov:
786
750
  raise "You need to either specify the scm as the first line in .externals, or use an option to specify it
787
751
  (such as --git or --svn)"
752
+ # :nocov:
788
753
  end
789
754
 
790
755
  main_project = self.class.project_class(scm).new(
@@ -799,12 +764,19 @@ Please use the --type option to tell ext which to use."
799
764
  end
800
765
 
801
766
  def infer_scm(path)
802
- self.class.registered_scms.each do |scm|
803
- return scm if self.class.project_class(scm).scm_path?(path)
767
+ registered_scms.find do |scm|
768
+ project_class(scm).scm_path?(path)
804
769
  end
805
- nil
806
770
  end
807
- end
808
- end
809
771
 
772
+ private
773
+
774
+ def registered_scms
775
+ self.class.registered_scms
776
+ end
810
777
 
778
+ def project_class(scm)
779
+ self.class.project_class(scm)
780
+ end
781
+ end
782
+ end