lib/modulesync.rb in modulesync-2.0.2 vs lib/modulesync.rb in modulesync-2.1.0

- old
+ new

@@ -1,17 +1,21 @@ require 'fileutils' require 'pathname' + require 'modulesync/cli' require 'modulesync/constants' -require 'modulesync/git' require 'modulesync/hook' +require 'modulesync/puppet_module' require 'modulesync/renderer' require 'modulesync/settings' require 'modulesync/util' + require 'monkey_patches' module ModuleSync # rubocop:disable Metrics/ModuleLength + class Error < StandardError; end + include Constants def self.config_defaults { :project_root => 'modules/', @@ -19,18 +23,18 @@ :configs => '.', :tag_pattern => '%s' } end + def self.options + @options + end + def self.local_file(config_path, file) File.join(config_path, MODULE_FILES_DIR, file) end - def self.module_file(project_root, namespace, puppet_module, *parts) - File.join(project_root, namespace, puppet_module, *parts) - end - # List all template files. # # Only select *.erb files, and strip the extension. This way all the code will only have to handle bare paths, # except when reading the actual ERB text def self.find_template_files(local_template_dir) @@ -48,27 +52,26 @@ def self.relative_names(file_list, path) file_list.map { |file| file.sub(/#{path}/, '') } end - def self.managed_modules(config_file, filter, negative_filter) + def self.managed_modules + config_file = config_path(options[:managed_modules_conf], options) + filter = options[:filter] + negative_filter = options[:negative_filter] + managed_modules = Util.parse_config(config_file) if managed_modules.empty? $stderr.puts "No modules found in #{config_file}." \ ' Check that you specified the right :configs directory and :managed_modules_conf file.' exit 1 end managed_modules.select! { |m| m =~ Regexp.new(filter) } unless filter.nil? managed_modules.reject! { |m| m =~ Regexp.new(negative_filter) } unless negative_filter.nil? - managed_modules + managed_modules.map { |given_name, options| PuppetModule.new(given_name, options) } end - def self.module_name(module_name, default_namespace) - return [default_namespace, module_name] unless module_name.include?('/') - ns, mod = module_name.split('/') - end - def self.hook(options) hook = Hook.new(HOOK_FILE, options) case options[:hook] when 'activate' @@ -76,68 +79,70 @@ when 'deactivate' hook.deactivate end end - def self.manage_file(filename, settings, options) + def self.manage_file(puppet_module, filename, settings, options) namespace = settings.additional_settings[:namespace] module_name = settings.additional_settings[:puppet_module] configs = settings.build_file_configs(filename) - target_file = module_file(options[:project_root], namespace, module_name, filename) + target_file = puppet_module.path(filename) if configs['delete'] Renderer.remove(target_file) else templatename = local_file(options[:configs], filename) begin erb = Renderer.build(templatename) # Meta data passed to the template as @metadata[:name] metadata = { :module_name => module_name, - :workdir => module_file(options[:project_root], namespace, module_name), + :workdir => puppet_module.working_directory, :target_file => target_file, } template = Renderer.render(erb, configs, metadata) Renderer.sync(template, target_file) - rescue # rubocop:disable Lint/RescueWithoutErrorClass - $stderr.puts "Error while rendering #{filename}" + rescue StandardError => e + $stderr.puts "#{puppet_module.given_name}: Error while rendering file: '#{filename}'" raise end end end - def self.manage_module(puppet_module, module_files, module_options, defaults, options) - default_namespace = options[:namespace] - if module_options.is_a?(Hash) && module_options.key?(:namespace) - default_namespace = module_options[:namespace] - end - namespace, module_name = module_name(puppet_module, default_namespace) - git_repo = File.join(namespace, module_name) - unless options[:offline] - Git.pull(options[:git_base], git_repo, options[:branch], options[:project_root], module_options || {}) - end + def self.manage_module(puppet_module, module_files, defaults) + puts "Syncing '#{puppet_module.given_name}'" + puppet_module.repository.prepare_workspace(options[:branch]) unless options[:offline] - module_configs = Util.parse_config(module_file(options[:project_root], namespace, module_name, MODULE_CONF_FILE)) + module_configs = Util.parse_config puppet_module.path(MODULE_CONF_FILE) settings = Settings.new(defaults[GLOBAL_DEFAULTS_KEY] || {}, defaults, module_configs[GLOBAL_DEFAULTS_KEY] || {}, module_configs, - :puppet_module => module_name, + :puppet_module => puppet_module.repository_name, :git_base => options[:git_base], - :namespace => namespace) + :namespace => puppet_module.repository_namespace) + settings.unmanaged_files(module_files).each do |filename| - $stdout.puts "Not managing #{filename} in #{module_name}" + $stdout.puts "Not managing '#{filename}' in '#{puppet_module.given_name}'" end files_to_manage = settings.managed_files(module_files) - files_to_manage.each { |filename| manage_file(filename, settings, options) } + files_to_manage.each { |filename| manage_file(puppet_module, filename, settings, options) } if options[:noop] - Git.update_noop(git_repo, options) - options[:pr] && pr(module_options).manage(namespace, module_name, options) + puts "Using no-op. Files in '#{puppet_module.given_name}' may be changed but will not be committed." + puppet_module.repository.show_changes(options) + options[:pr] && \ + pr(puppet_module).manage(puppet_module.repository_namespace, puppet_module.repository_name, options) elsif !options[:offline] - pushed = Git.update(git_repo, files_to_manage, options) - pushed && options[:pr] && pr(module_options).manage(namespace, module_name, options) + pushed = puppet_module.repository.submit_changes(files_to_manage, options) + # Only bump/tag if pushing didn't fail (i.e. there were changes) + if pushed && options[:bump] + new = puppet_module.bump(options[:message], options[:changelog]) + puppet_module.repository.tag(new, options[:tag_pattern]) if options[:tag] + end + pushed && options[:pr] && \ + pr(puppet_module).manage(puppet_module.repository_namespace, puppet_module.repository_name, options) end end def self.config_path(file, options) return file if Pathname.new(file).absolute? @@ -146,13 +151,14 @@ def config_path(file, options) self.class.config_path(file, options) end - def self.update(options) - options = config_defaults.merge(options) + def self.update(cli_options) + @options = config_defaults.merge(cli_options) defaults = Util.parse_config(config_path(CONF_FILE, options)) + if options[:pr] unless options[:branch] $stderr.puts 'A branch must be specified with --branch to use --pr!' raise end @@ -162,31 +168,31 @@ local_template_dir = config_path(MODULE_FILES_DIR, options) local_files = find_template_files(local_template_dir) module_files = relative_names(local_files, local_template_dir) - managed_modules = self.managed_modules(config_path(options[:managed_modules_conf], options), - options[:filter], - options[:negative_filter]) - errors = false # managed_modules is either an array or a hash - managed_modules.each do |puppet_module, module_options| + managed_modules.each do |puppet_module| begin - mod_options = module_options.nil? ? nil : Util.symbolize_keys(module_options) - manage_module(puppet_module, module_files, mod_options, defaults, options) - rescue # rubocop:disable Lint/RescueWithoutErrorClass - $stderr.puts "Error while updating #{puppet_module}" + manage_module(puppet_module, module_files, defaults) + rescue ModuleSync::Error, Git::GitExecuteError => e + message = e.message || "Error during '#{options[:command]}'" + $stderr.puts "#{puppet_module.given_name}: #{message}" + exit 1 unless options[:skip_broken] + errors = true + $stdout.puts "Skipping '#{puppet_module.given_name}' as update process failed" + rescue StandardError => e raise unless options[:skip_broken] errors = true - $stdout.puts "Skipping #{puppet_module} as update process failed" + $stdout.puts "Skipping '#{puppet_module.given_name}' as update process failed" end end exit 1 if errors && options[:fail_on_warnings] end - def self.pr(module_options) - module_options ||= {} + def self.pr(puppet_module) + module_options = puppet_module.options github_conf = module_options[:github] gitlab_conf = module_options[:gitlab] if !github_conf.nil? base_url = github_conf[:base_url] || ENV.fetch('GITHUB_BASE_URL', 'https://api.github.com')