ext 1.1.2 → 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.2'
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[:scm] = 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
- raise "No such directory: #{dir}" unless File.exists?(dir) && File.directory?(dir)
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"
@@ -237,8 +207,10 @@ module Externals
237
207
  print_commands(SHORT_COMMANDS_HASH)
238
208
  end
239
209
 
210
+ @registered_scms = nil
240
211
  def self.registered_scms
241
212
  return @registered_scms if @registered_scms
213
+
242
214
  @registered_scms ||= []
243
215
 
244
216
  scmdir = File.join(File.dirname(__FILE__), 'scms')
@@ -254,9 +226,10 @@ module Externals
254
226
 
255
227
  def projects
256
228
  return @projects if @projects
229
+
257
230
  @projects = []
258
231
  configuration.sections.each do |section|
259
- @projects << Ext.project_class(section[:scm]||infer_scm(section[:repository])).new(
232
+ @projects << Ext.project_class(section[:scm] || infer_scm(section[:repository])).new(
260
233
  section.attributes.merge(:path => section.title))
261
234
  end
262
235
  #let's set the parents of these projects
@@ -271,11 +244,14 @@ module Externals
271
244
  project ||= subprojects.detect do |p|
272
245
  File.split(p.path).last.strip == name
273
246
  end
274
- project ||= subprojects.detect do |p|
247
+ project || subprojects.detect do |p|
248
+ # TODO: test (or delete) this code path!
249
+ # :nocov:
275
250
  p.name == name
251
+ # :nocov:
276
252
  end
277
253
  end
278
- alias :subproject :subproject_by_name_or_path
254
+ alias subproject subproject_by_name_or_path
279
255
 
280
256
  def subprojects
281
257
  s = []
@@ -286,14 +262,14 @@ module Externals
286
262
  end
287
263
 
288
264
  def main_project
289
- projects.detect {|p| p.main_project?}
265
+ projects.detect(&:main_project?)
290
266
  end
291
267
 
292
268
  def configuration
293
269
  return @configuration if @configuration
294
270
 
295
271
  file_string = ''
296
- if File.exists? '.externals'
272
+ if File.exist?('.externals')
297
273
  open('.externals', 'r') do |f|
298
274
  file_string = f.read
299
275
  end
@@ -310,45 +286,22 @@ module Externals
310
286
  def initialize options = {}
311
287
  super()
312
288
 
289
+ @configuration = nil
290
+ @projects = nil
291
+
313
292
  scm = configuration['.']
314
293
  scm = scm['scm'] if scm
315
- scm ||= options[:scm]
316
-
317
- type = configuration['.']
318
- type = type['type'] if type
319
-
320
- type ||= options[:type]
321
-
322
- if type
323
- install_project_type type
324
- else
325
- possible_project_types = self.class.project_types.select do |project_type|
326
- self.class.project_type_detector(project_type).detected?
327
- end
328
-
329
- if possible_project_types.size > 1
330
- raise "We found multiple project types that this could be: #{possible_project_types.join(',')}
331
- Please use
332
- the --type option to tell ext which to use."
333
- else
334
- possible_project_types.each do |project_type|
335
- install_project_type project_type
336
- end
337
- end
338
- end
294
+ scm || options[:scm]
339
295
  end
340
296
 
341
297
  def self.project_class(scm)
342
- Externals.module_eval("#{scm.to_s.cap_first}Project", __FILE__, __LINE__)
298
+ Externals.const_get("#{scm.to_s.cap_first}Project")
343
299
  end
344
300
 
345
301
  def self.project_classes
346
- retval = []
347
- registered_scms.each do |scm|
348
- retval << project_class(scm)
302
+ registered_scms.map do |scm|
303
+ project_class(scm)
349
304
  end
350
-
351
- retval
352
305
  end
353
306
 
354
307
  SHORT_COMMANDS.each do |command_name|
@@ -360,20 +313,22 @@ Please use
360
313
  end
361
314
 
362
315
  if project_name_or_path
363
- project = subprojects.detect do |project|
364
- project.name == project_name_or_path || project.path == project_name_or_path
316
+ project = subprojects.detect do |p|
317
+ p.name == project_name_or_path || p.path == project_name_or_path
365
318
  end
366
319
 
320
+ # :nocov:
367
321
  raise "no such project" unless project
322
+ # :nocov:
368
323
 
369
324
  project.send command_name, args, options
370
325
  else
371
- subprojects.each {|p| p.send(*([command_name, args, options].flatten))}
326
+ subprojects.each {|p| p.send(*[command_name, args, options].flatten)}
372
327
  end
373
328
  end
374
329
  end
375
330
 
376
- def freeze args, options
331
+ def freeze args, _options
377
332
  project = subproject_by_name_or_path(args[0])
378
333
 
379
334
  raise "No such project named #{args[0]}" unless project
@@ -387,7 +342,10 @@ Please use
387
342
  if branch
388
343
  section[:branch] = branch
389
344
  else
345
+ # TODO: test (or delete) this code path!
346
+ # :nocov:
390
347
  section.rm_setting :branch
348
+ # :nocov:
391
349
  end
392
350
  end
393
351
  section[:revision] = revision
@@ -397,7 +355,7 @@ Please use
397
355
  subproject_by_name_or_path(args[0]).up
398
356
  end
399
357
 
400
- def unfreeze args, options
358
+ def unfreeze args, _options
401
359
  project = subproject_by_name_or_path(args[0])
402
360
 
403
361
  raise "No such project named #{args[0]}" unless project
@@ -405,8 +363,10 @@ Please use
405
363
  section = configuration[project.path]
406
364
 
407
365
  unless section[:revision]
366
+ # :nocov:
408
367
  puts "Uhh... #{project.name} wasn't frozen, so I can't unfreeze it."
409
- exit
368
+ exit 1
369
+ # :nocov:
410
370
  end
411
371
 
412
372
  section.rm_setting :revision
@@ -417,9 +377,11 @@ Please use
417
377
  end
418
378
 
419
379
  def install args, options
420
- if !File.exists? '.externals'
421
- STDERR.puts "This project does not appear to be managed by externals. Try 'ext init' first"
380
+ if !File.exist?('.externals')
381
+ # :nocov:
382
+ warn "This project does not appear to be managed by externals. Try 'ext init' first"
422
383
  exit NO_EXTERNALS_FILE
384
+ # :nocov:
423
385
  end
424
386
  repository = args[0]
425
387
  path = args[1]
@@ -431,15 +393,17 @@ Please use
431
393
  scm ||= infer_scm(repository)
432
394
 
433
395
  unless scm
434
- STDERR.puts "Unable to determine SCM from the repository name.
396
+ # :nocov:
397
+ warn "Unable to determine SCM from the repository name.
435
398
  You need to either specify the scm used to manage the subproject
436
399
  that you are installing. Use an option to specify it
437
400
  (such as --git or --svn)"
438
401
  exit COULD_NOT_DETERMINE_SCM
402
+ # :nocov:
439
403
  end
440
404
 
441
405
  project = self.class.project_class(scm).new(:repository => repository,
442
- :path => path || path_calculator.new, :scm => scm)
406
+ :path => path, :scm => scm)
443
407
  path = project.path
444
408
 
445
409
  raise "no path" unless path
@@ -461,7 +425,11 @@ that you are installing. Use an option to specify it
461
425
  end
462
426
 
463
427
  def uninstall args, options
464
- raise "Hmm... there's no .externals file in this directory." if !File.exists? '.externals'
428
+ unless File.exist?('.externals')
429
+ # :nocov:
430
+ raise "Hmm... there's no .externals file in this directory."
431
+ # :nocov:
432
+ end
465
433
 
466
434
  project = subproject_by_name_or_path(args[0])
467
435
 
@@ -469,7 +437,6 @@ that you are installing. Use an option to specify it
469
437
 
470
438
  main_project.drop_from_ignore project.path
471
439
 
472
-
473
440
  configuration.remove_section(project.path)
474
441
  configuration.write '.externals'
475
442
  reload_configuration
@@ -481,15 +448,18 @@ that you are installing. Use an option to specify it
481
448
  end
482
449
  end
483
450
 
484
- def update_ignore args, options
451
+ def update_ignore _args, options
485
452
  scm = configuration['.']
486
453
  scm = scm['scm'] if scm
487
454
 
488
455
  scm ||= options[:scm]
489
456
 
490
457
  unless scm
491
- 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
492
461
  (such as --git or --svn)"
462
+ # :nocov:
493
463
  end
494
464
 
495
465
  project = self.class.project_class(scm).new(:path => ".")
@@ -501,10 +471,10 @@ that you are installing. Use an option to specify it
501
471
  end
502
472
  end
503
473
 
504
- def touch_emptydirs args, options
474
+ def touch_emptydirs _args, _options
505
475
  require 'find'
506
476
 
507
- excludes = ['.','..','.svn', '.git']
477
+ excludes = ['.', '..', '.svn', '.git']
508
478
 
509
479
  excludes.dup.each do |exclude|
510
480
  excludes << "./#{exclude}"
@@ -516,23 +486,26 @@ that you are installing. Use an option to specify it
516
486
  if File.directory?(f)
517
487
  excluded = false
518
488
  File.split(f).each do |part|
519
- exclude ||= excludes.index(part)
489
+ excluded ||= excludes.index(part)
520
490
  end
521
491
 
522
- if !excluded && ((Dir.entries(f) - excludes).size == 0)
492
+ if !excluded && (Dir.entries(f) - excludes).empty?
523
493
  paths << f
524
494
  end
525
495
  end
526
496
  end
527
497
 
528
498
  paths.each do |p|
529
- 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
530
505
  end
531
-
532
506
  end
533
507
 
534
-
535
- def status args, options
508
+ def status _args, options
536
509
  options ||= {}
537
510
  scm = options[:scm]
538
511
 
@@ -542,24 +515,27 @@ that you are installing. Use an option to specify it
542
515
  end
543
516
 
544
517
  if !scm
545
- possible_project_classes = self.class.project_classes.select do |project_class|
546
- project_class.detected?
547
- end
518
+ # TODO: test (or delete) this code path!
519
+ # :nocov:
520
+ possible_project_classes = self.class.project_classes.select(&:detected?)
548
521
 
549
- 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?
550
523
  if possible_project_classes.size > 1
551
524
  raise "This project appears to be managed by multiple SCMs: #{
552
- possible_project_classes.map(&:to_s).join(',')}
525
+ possible_project_classes.join(',')}
553
526
  Please explicitly declare the SCM (by using --git or --svn, or,
554
527
  by creating the .externals file manually"
555
528
  end
556
529
 
557
530
  scm = possible_project_classes.first.scm
531
+ # :nocov:
558
532
  end
559
533
 
560
534
  unless scm
535
+ # :nocov:
561
536
  raise "You need to either specify the scm as the first line in .externals, or use an option to specify it
562
537
  (such as --git or --svn)"
538
+ # :nocov:
563
539
  end
564
540
 
565
541
  project = main_project
@@ -581,24 +557,27 @@ by creating the .externals file manually"
581
557
  end
582
558
 
583
559
  if !scm
584
- possible_project_classes = self.class.project_classes.select do |project_class|
585
- project_class.detected?
586
- end
560
+ # TODO: test (or delete) this code path!
561
+ # :nocov:
562
+ possible_project_classes = self.class.project_classes.select(&:detected?)
587
563
 
588
- 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?
589
565
  if possible_project_classes.size > 1
590
566
  raise "This project appears to be managed by multiple SCMs: #{
591
- possible_project_classes.map(&:to_s).join(',')}
567
+ possible_project_classes.join(',')}
592
568
  Please explicitly declare the SCM (by using --git or --svn, or,
593
569
  by creating the .externals file manually"
594
570
  end
595
571
 
596
572
  scm = possible_project_classes.first.scm
573
+ # :nocov:
597
574
  end
598
575
 
599
576
  unless scm
577
+ # :nocov:
600
578
  raise "You need to either specify the scm as the first line in .externals, or use an option to specify it
601
579
  (such as --git or --svn)"
580
+ # :nocov:
602
581
  end
603
582
 
604
583
  old_config = configuration
@@ -618,14 +597,14 @@ by creating the .externals file manually"
618
597
 
619
598
  removed_project_paths = old_config.removed_project_paths(
620
599
  configuration
621
- ).select{|path| File.exists?(path)}
600
+ ).select{|path| File.exist?(path)}
622
601
 
623
602
  if !removed_project_paths.empty?
624
603
  puts "WARNING: The following subprojects are no longer being maintained in the
625
604
  .externals file. You might want to remove them. You can copy and paste the
626
605
  commands below if you actually wish to delete them."
627
606
  removed_project_paths.each do |path|
628
- if File.exists? path
607
+ if File.exist?(path)
629
608
  puts " rm -r #{path}"
630
609
  end
631
610
  end
@@ -633,7 +612,7 @@ commands below if you actually wish to delete them."
633
612
  end
634
613
  end
635
614
 
636
- def update args, options
615
+ def update _args, options
637
616
  options ||= {}
638
617
  scm = options[:scm]
639
618
 
@@ -643,8 +622,10 @@ commands below if you actually wish to delete them."
643
622
  end
644
623
 
645
624
  unless scm
625
+ # :nocov:
646
626
  raise "You need to either specify the scm as the first line in .externals, or use an option to specify it
647
627
  (such as --git or --svn)"
628
+ # :nocov:
648
629
  end
649
630
 
650
631
  project = main_project
@@ -667,7 +648,7 @@ commands below if you actually wish to delete them."
667
648
  end
668
649
 
669
650
  Dir.chdir path do
670
- self.class.new({}).co [], {} #args, options
651
+ self.class.new({}).co [], {}
671
652
  end
672
653
  end
673
654
 
@@ -680,7 +661,10 @@ commands below if you actually wish to delete them."
680
661
  main_project = do_checkout_or_export repository, path, options, :export
681
662
 
682
663
  if path == "."
664
+ # TODO: test (or delete) this code path!
665
+ # :nocov:
683
666
  path = main_project.name
667
+ # :nocov:
684
668
  end
685
669
 
686
670
  Dir.chdir path do
@@ -689,44 +673,29 @@ commands below if you actually wish to delete them."
689
673
  end
690
674
 
691
675
  def init args, options = {}
692
- raise ".externals already exists" if File.exists? '.externals'
676
+ # :nocov:
677
+ raise ".externals already exists" if File.exist?('.externals')
678
+ # :nocov:
693
679
 
694
680
  scm = options[:scm]
695
- type = options[:type]
696
681
 
697
682
  if !scm
698
- possible_project_classes = self.class.project_classes.select do |project_class|
699
- project_class.detected?
700
- end
683
+ possible_project_classes = self.class.project_classes.select(&:detected?)
701
684
 
702
- 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?
703
686
  if possible_project_classes.size > 1
687
+ # :nocov:
704
688
  raise "This project appears to be managed by multiple SCMs: #{
705
- possible_project_classes.map(&:to_s).join(',')}
689
+ possible_project_classes.join(',')}
706
690
  Please explicitly declare the SCM (using --git or --svn, or, by creating .externals manually"
691
+ # :nocov:
707
692
  end
708
693
 
709
694
  scm = possible_project_classes.first.scm
710
695
  end
711
696
 
712
- if !type
713
- possible_project_types = self.class.project_types.select do |project_type|
714
- self.class.project_type_detector(project_type).detected?
715
- end
716
-
717
- if possible_project_types.size > 1
718
- raise "We found multiple project types that this could be: #{possible_project_types.join(',')}
719
- Please use the --type option to tell ext which to use."
720
- elsif possible_project_types.size == 0
721
- puts "WARNING: We could not automatically determine the project type.
722
- Be sure to specify paths when adding subprojects to your .externals file"
723
- else
724
- type = possible_project_types.first
725
- end
726
- end
727
-
728
697
  config = Configuration::Configuration.new_empty
729
- raise ".externals already exists" if File.exists?('.externals')
698
+ raise ".externals already exists" if File.exist?('.externals')
730
699
 
731
700
  config.add_empty_section '.'
732
701
 
@@ -738,33 +707,30 @@ Please use the --type option to tell ext which to use."
738
707
  options[:branch]
739
708
  )
740
709
  elsif args[0]
710
+ # TODO: test (or delete) this code path!
711
+ # :nocov:
741
712
  config['.'][:repository] = args[0].strip
713
+ # :nocov:
742
714
  end
743
715
  end
744
716
 
745
717
  config['.'][:scm] = scm
746
- config['.'][:type] = type if type
747
718
 
748
719
  config.write '.externals'
749
720
  reload_configuration
750
721
  end
751
722
 
752
- def version(args, options)
723
+ def version(_args, _options)
753
724
  puts Externals::VERSION
754
725
  end
755
726
 
756
- def self.project_type_detector name
757
- Externals.module_eval("#{name.classify}Detector", __FILE__, __LINE__)
758
- end
759
-
760
- def install_project_type name
761
- self.path_calculator = Externals.module_eval("#{name.classify}ProjectType::DefaultPathCalculator", __FILE__, __LINE__)
762
- end
763
-
764
727
  protected
728
+
765
729
  def do_checkout_or_export repository, path, options, sym
766
- if File.exists?('.externals')
730
+ if File.exist?('.externals')
731
+ # :nocov:
767
732
  raise "seems main project is already checked out here?"
733
+ # :nocov:
768
734
  else
769
735
  #We appear to be attempting to checkout/export a main project
770
736
  scm = options[:scm]
@@ -772,13 +738,18 @@ Please use the --type option to tell ext which to use."
772
738
  scm ||= infer_scm(repository)
773
739
 
774
740
  if !scm
741
+ # TODO: test (or delete) this code path!
742
+ # :nocov:
775
743
  scm ||= configuration['main']
776
744
  scm &&= scm['scm']
745
+ # :nocov:
777
746
  end
778
747
 
779
748
  unless scm
749
+ # :nocov:
780
750
  raise "You need to either specify the scm as the first line in .externals, or use an option to specify it
781
751
  (such as --git or --svn)"
752
+ # :nocov:
782
753
  end
783
754
 
784
755
  main_project = self.class.project_class(scm).new(
@@ -793,12 +764,19 @@ Please use the --type option to tell ext which to use."
793
764
  end
794
765
 
795
766
  def infer_scm(path)
796
- self.class.registered_scms.each do |scm|
797
- return scm if self.class.project_class(scm).scm_path?(path)
767
+ registered_scms.find do |scm|
768
+ project_class(scm).scm_path?(path)
798
769
  end
799
- nil
800
770
  end
801
- end
802
- end
803
771
 
772
+ private
773
+
774
+ def registered_scms
775
+ self.class.registered_scms
776
+ end
804
777
 
778
+ def project_class(scm)
779
+ self.class.project_class(scm)
780
+ end
781
+ end
782
+ end