Class: OctocatalogDiff::CatalogUtil::Bootstrap

Inherits:
Object
  • Object
show all
Defined in:
lib/octocatalog-diff/catalog-util/bootstrap.rb

Overview

Methods to bootstrap a directory. Intended to be called from cli. This handles parallelization of bootstrap, and formats arguments as expected by the higher level bootstrap script.

Class Method Summary collapse

Class Method Details

.bootstrap_directory(options, logger) ⇒ Object

Performs the actual bootstrap of a directory. Intended to be called by bootstrap_directory_parallelizer above, or as part of the parallelized catalog build process from util/catalogs.

Parameters:

  • options (Hash)

    Directory options: branch, path, tag

  • logger (Logger)

    Logger object

Raises:

  • (ArgumentError)

90
91
92
93
94
95
96
97
98
# File 'lib/octocatalog-diff/catalog-util/bootstrap.rb', line 90

def self.bootstrap_directory(options, logger)
  raise ArgumentError, ':path must be supplied' unless options[:path]
  FileUtils.mkdir_p(options[:path]) unless Dir.exist?(options[:path])
  git_checkout(logger, options) if options[:branch]
  unless options[:bootstrap_script].nil?
    install_bootstrap_script(logger, options)
    run_bootstrap(logger, options)
  end
end

.bootstrap_directory_parallelizer(options, logger) ⇒ Object

Bootstrap directories specified by –bootstrapped-from-dir and –bootstrapped-to-dir command line options. Bootstrapping occurs in parallel. This takes no parameters (options come from options) and returns nothing (it raises an exception if something fails).


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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
80
81
82
83
84
# File 'lib/octocatalog-diff/catalog-util/bootstrap.rb', line 19

def self.bootstrap_directory_parallelizer(options, logger)
  # What directories do we have to bootstrap?
  dirs = []

  unless options[:bootstrapped_from_dir].nil?
    if options[:from_env] == '.'
      message = 'Must specify a from-branch other than . when using --bootstrapped-from-dir!' \
                ' Please use "-f <from_branch>" argument.'
      logger.error(message)
      raise OctocatalogDiff::Errors::BootstrapError, message
    end

    opts = options.merge(branch: options[:from_env],
                         path: options[:bootstrapped_from_dir],
                         tag: 'from_dir',
                         dir: options[:basedir])
    dirs << opts
  end

  unless options[:bootstrapped_to_dir].nil?
    if options[:to_env] == '.'
      message = 'Must specify a to-branch other than . when using --bootstrapped-to-dir!' \
                ' Please use "-t <to_branch>" argument.'
      logger.error(message)
      raise OctocatalogDiff::Errors::BootstrapError, message
    end

    opts = options.merge(branch: options[:to_env],
                         path: options[:bootstrapped_to_dir],
                         tag: 'to_dir')
    dirs << opts
  end

  # If there are no directories given, advise the user to supply the necessary options
  if dirs.empty?
    return unless options[:cached_master_dir].nil?
    message = 'Specify one or more of --bootstrapped-from-dir / --bootstrapped-to-dir / --cached-master-dir' \
              ' when using --bootstrap_then_exit'
    logger.error(message)
    raise OctocatalogDiff::Errors::BootstrapError, message
  end

  # Bootstrap the directories in parallel. Since there are no results here that we
  # care about, increment the success counter for each run that did not throw an exception.
  tasks = dirs.map do |x|
    OctocatalogDiff::Util::Parallel::Task.new(
      method: method(:bootstrap_directory),
      description: "bootstrap #{x[:tag]} #{x[:path]} for #{x[:branch]}",
      args: x
    )
  end

  logger.debug("Begin #{dirs.size} bootstrap(s)")
  parallel_tasks = OctocatalogDiff::Util::Parallel.run_tasks(tasks, logger, options[:parallel])
  parallel_tasks.each do |result|
    if result.status
      logger.debug("Success bootstrap_directory for #{result.args[:tag]}")
    else
      # Believed to be a bug condition, since error should have already been raised if this happens.
      # :nocov:
      errmsg = "Failed bootstrap_directory for #{result.args[:tag]}: #{result.exception.class} #{result.exception.message}"
      raise OctocatalogDiff::Errors::BootstrapError, errmsg
      # :nocov:
    end
  end
end

.git_checkout(logger, options) ⇒ Object

Perform git checkout

Parameters:

  • logger (Logger)

    Logger object

  • options (Hash)

    Options (need to contain: basedir, branch, path)


103
104
105
106
107
108
109
110
# File 'lib/octocatalog-diff/catalog-util/bootstrap.rb', line 103

def self.git_checkout(logger, options)
  logger.debug("Begin git checkout #{options[:basedir]}:#{options[:branch]} -> #{options[:path]}")
  OctocatalogDiff::CatalogUtil::Git.check_out_git_archive(options.merge(logger: logger))
  logger.debug("Success git checkout #{options[:basedir]}:#{options[:branch]} -> #{options[:path]}")
rescue OctocatalogDiff::Errors::GitCheckoutError => exc
  logger.error("Git checkout error: #{exc}")
  raise OctocatalogDiff::Errors::BootstrapError, exc
end

.install_bootstrap_script(logger, opts) ⇒ Object

Install bootstrap script in the target directory. This allows proper bootstrapping from the latest version of the script, not the script that was in place at the time that directory's branch was committed.

Parameters:

  • logger (Logger)

    Logger object

  • opts (Hash)

    Directory options

Raises:


117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/octocatalog-diff/catalog-util/bootstrap.rb', line 117

def self.install_bootstrap_script(logger, opts)
  # Verify that bootstrap file exists
  src = if opts[:bootstrap_script].start_with? '/'
    opts[:bootstrap_script]
  else
    File.join(opts[:basedir], opts[:bootstrap_script])
  end
  raise OctocatalogDiff::Errors::BootstrapError, "Bootstrap script #{src} does not exist" unless File.file?(src)

  logger.debug('Begin install bootstrap script in target directory')

  # Create destination directory if needed
  dest = File.join(opts[:path], opts[:bootstrap_script])
  dest_dir = File.dirname(dest)
  FileUtils.mkdir_p(dest_dir) unless File.directory?(dest_dir)

  # Copy file and make executable
  FileUtils.cp src, dest
  FileUtils.chmod 0o755, dest
  logger.debug("Success: copied #{src} to #{dest}")
end

.run_bootstrap(logger, opts) ⇒ Object

Execute the bootstrap.

Parameters:

  • logger (Logger)

    Logger object

  • opts (Hash)

    Directory options


142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/octocatalog-diff/catalog-util/bootstrap.rb', line 142

def self.run_bootstrap(logger, opts)
  logger.debug("Begin bootstrap with '#{opts[:bootstrap_script]}' in #{opts[:path]}")
  result = OctocatalogDiff::Bootstrap.bootstrap(opts)
  if opts[:debug_bootstrap] || result[:status_code] > 0
    output = result[:output].split(/[\r\n]+/)
    output.each { |x| logger.debug("Bootstrap: #{x}") }
  end
  unless (result[:status_code]).zero?
    raise OctocatalogDiff::Errors::BootstrapError, "bootstrap failed for #{opts[:path]}: #{result[:output]}"
  end
  logger.debug("Success bootstrap in #{opts[:path]}")
  result[:output]
end