lib/pdk/generate/module.rb in pdk-akerl-1.9.1.1 vs lib/pdk/generate/module.rb in pdk-akerl-1.14.0.1

- old
+ new

@@ -1,27 +1,15 @@ -require 'etc' -require 'pathname' -require 'fileutils' -require 'tty-prompt' +require 'pdk/util/filesystem' -require 'pdk' -require 'pdk/logger' -require 'pdk/module/metadata' -require 'pdk/module/templatedir' -require 'pdk/cli/exec' -require 'pdk/cli/util' -require 'pdk/cli/util/interview' -require 'pdk/cli/util/option_validator' -require 'pdk/util' -require 'pdk/util/version' - module PDK module Generate class Module extend PDK::Util::Filesystem def self.validate_options(opts) + require 'pdk/cli/util/option_validator' + unless PDK::CLI::Util::OptionValidator.valid_module_name?(opts[:module_name]) error_msg = _( "'%{module_name}' is not a valid module name.\n" \ 'Module names must begin with a lowercase letter and can only include lowercase letters, digits, and underscores.', ) % { module_name: opts[:module_name] } @@ -31,10 +19,16 @@ target_dir = File.expand_path(opts[:target_dir]) raise PDK::CLI::ExitWithError, _("The destination directory '%{dir}' already exists") % { dir: target_dir } if File.exist?(target_dir) end def self.invoke(opts = {}) + require 'pdk/module/templatedir' + require 'pdk/util' + require 'pdk/util/template_uri' + require 'fileutils' + require 'pathname' + validate_options(opts) unless opts[:module_name].nil? metadata = prepare_metadata(opts) target_dir = File.expand_path(opts[:target_dir] || opts[:module_name]) @@ -52,15 +46,16 @@ temp_target_dir = PDK::Util.make_tmpdir_name('pdk-module-target') prepare_module_directory(temp_target_dir) - template_url = opts.fetch(:'template-url', PDK::Util.default_template_url) + template_uri = PDK::Util::TemplateURI.new(opts) begin - PDK::Module::TemplateDir.new(template_url, metadata.data, true) do |templates| - templates.render do |file_path, file_content| + PDK::Module::TemplateDir.new(template_uri, metadata.data, true) do |templates| + templates.render do |file_path, file_content, file_status| + next if file_status == :delete file = Pathname.new(temp_target_dir) + file_path file.dirname.mkpath write_file(file, file_content) end @@ -72,25 +67,33 @@ end rescue ArgumentError => e raise PDK::CLI::ExitWithError, e end - if template_url == PDK::Util.puppetlabs_template_url - # If the user specifies our template via the command line, remove the - # saved template-url answer. + # Only update the answers files after metadata has been written. + require 'pdk/answer_file' + if template_uri.default? + # If the user specifies our default template url via the command + # line, remove the saved template-url answer so that the template_uri + # resolution can find new default URLs in the future. PDK.answers.update!('template-url' => nil) if opts.key?(:'template-url') else - # Save the template-url answer if the module was generated using - # a template other than ours. - PDK.answers.update!('template-url' => template_url) + # Save the template-url answers if the module was generated using a + # template/reference other than ours. + PDK.answers.update!('template-url' => template_uri.metadata_format) end begin if FileUtils.mv(temp_target_dir, target_dir) - Dir.chdir(target_dir) { PDK::Util::Bundler.ensure_bundle! } unless opts[:'skip-bundle-install'] + unless opts[:'skip-bundle-install'] + Dir.chdir(target_dir) do + require 'pdk/util/bundler' + PDK::Util::Bundler.ensure_bundle! + end + end - PDK.logger.info(_('Module \'%{name}\' generated at path \'%{path}\', from template \'%{template_url}\'.') % { name: opts[:module_name], path: target_dir, template_url: template_url }) + PDK.logger.info _('Module \'%{name}\' generated at path \'%{path}\', from template \'%{url}\'.') % { name: opts[:module_name], path: target_dir, url: template_uri.git_remote } PDK.logger.info(_('In your module directory, add classes with the \'pdk new class\' command.')) end rescue Errno::EACCES => e raise PDK::CLI::FatalError, _("Failed to move '%{source}' to '%{target}': %{message}") % { source: temp_target_dir, @@ -99,10 +102,12 @@ } end end def self.username_from_login + require 'etc' + login = Etc.getlogin || '' login_clean = login.downcase.gsub(%r{[^0-9a-z]}i, '') login_clean = 'username' if login_clean.empty? if login_clean != login @@ -113,26 +118,31 @@ login_clean end def self.prepare_metadata(opts = {}) + require 'pdk/answer_file' + require 'pdk/module/metadata' + opts[:username] = (opts[:username] || PDK.answers['forge_username'] || username_from_login).downcase defaults = PDK::Module::Metadata::DEFAULTS.dup defaults['name'] = "#{opts[:username]}-#{opts[:module_name]}" unless opts[:module_name].nil? defaults['author'] = PDK.answers['author'] unless PDK.answers['author'].nil? defaults['license'] = PDK.answers['license'] unless PDK.answers['license'].nil? - defaults['license'] = opts[:license] if opts.key? :license + defaults['license'] = opts[:license] if opts.key?(:license) metadata = PDK::Module::Metadata.new(defaults) module_interview(metadata, opts) unless opts[:'skip-interview'] metadata end def self.prepare_module_directory(target_dir) + require 'fileutils' + [ File.join(target_dir, 'examples'), File.join(target_dir, 'files'), File.join(target_dir, 'manifests'), File.join(target_dir, 'templates'), @@ -148,10 +158,13 @@ end end end def self.module_interview(metadata, opts = {}) + require 'pdk/module/metadata' + require 'pdk/cli/util/interview' + questions = [ { name: 'module_name', question: _('If you have a name for your module, add it here.'), help: _('This is the name that will be associated with your module, it should be relevant to the modules content.'), @@ -195,10 +208,11 @@ { name: 'operatingsystem_support', question: _('What operating systems does this module support?'), help: _('Use the up and down keys to move between the choices, space to select and enter to continue.'), required: true, + type: :multi_select, choices: PDK::Module::Metadata::OPERATING_SYSTEMS, default: PDK::Module::Metadata::DEFAULT_OPERATING_SYSTEMS.map do |os_name| # tty-prompt uses a 1-index PDK::Module::Metadata::OPERATING_SYSTEMS.keys.index(os_name) + 1 end, @@ -248,26 +262,36 @@ end end else questions.reject! { |q| q[:name] == 'module_name' } if opts.key?(:module_name) questions.reject! { |q| q[:name] == 'license' } if opts.key?(:license) - questions.reject! { |q| q[:forge_only] } unless opts.key?(:'full-interview') + questions.reject! { |q| q[:forge_only] } unless opts[:'full-interview'] end interview.add_questions(questions) - action = File.file?('metadata.json') ? _('update') : _('create') + if File.file?('metadata.json') + puts _( + "\nWe need to update the metadata.json file for this module, so we\'re going to ask you %{count} " \ + "questions.\n", + ) % { + count: interview.num_questions, + } + else + puts _( + "\nWe need to create the metadata.json file for this module, so we\'re going to ask you %{count} " \ + "questions.\n", + ) % { + count: interview.num_questions, + } + end + puts _( - "\nWe need to %{action} the metadata.json file for this module, so we\'re going to ask you %{count} " \ - "questions.\n" \ 'If the question is not applicable to this module, accept the default option ' \ 'shown after each question. You can modify any answers at any time by manually updating ' \ "the metadata.json file.\n\n", - ) % { - count: interview.num_questions, - action: action, - } + ) answers = interview.run if answers.nil? PDK.logger.info _('No answers given, interview cancelled.') @@ -291,10 +315,12 @@ answers['operatingsystem_support'].flatten! if answers.key?('operatingsystem_support') metadata.update!(answers) if opts[:prompt].nil? || opts[:prompt] + require 'pdk/cli/util' + continue = PDK::CLI::Util.prompt_for_yes( _('Metadata will be generated based on this information, continue?'), prompt: prompt, cancel_message: _('Interview cancelled; exiting.'), ) @@ -303,9 +329,10 @@ PDK.logger.info _('Process cancelled; exiting.') exit 0 end end + require 'pdk/answer_file' PDK.answers.update!( { 'forge_username' => opts[:username], 'author' => answers['author'], 'license' => answers['license'],