class Metasploit::Version::CLI

Command-line interface for ‘metasploit-version`. Used to run commands for managing the semantic version of a project.

Constants

DEVELOPMENT_DEPENDENCY_REGEXP

Matches pre-existing development dependency on metasploit-version for updating.

GEM_NAME

Name of this gem, for use in other projects that call ‘metasploit-version install`.

Public Instance Methods

install() click to toggle source

Adds ‘metasploit-version’ as a development dependency in this project’s gemspec.

@return [void]

# File lib/metasploit/version/cli.rb, line 96
def install
  ensure_development_dependency
  template('lib/versioned/version.rb.tt', "lib/#{namespaced_path}/version.rb")
  install_bundle
  template('CHANGELOG.md.tt', 'CHANGELOG.md')
  template('CONTRIBUTING.md.tt', 'CONTRIBUTING.md')
  template('RELEASING.md.tt', 'RELEASING.md')
  template('UPGRADING.md.tt', 'UPGRADING.md')
  setup_rspec
end

Private Instance Methods

capitalize(word) click to toggle source

Capitalizes words by converting the first character of ‘word` to upper case.

@param word [String] a lower case string @return [String]

# File lib/metasploit/version/cli.rb, line 113
def capitalize(word)
  word[0, 1].upcase + word[1 .. -1]
end
development_dependency_line() click to toggle source

The line injected into the gemspec by {#ensure_development_dependency}

@return [String]

# File lib/metasploit/version/cli.rb, line 120
def development_dependency_line
  "  spec.add_development_dependency '#{GEM_NAME}', '#{version_requirement}'\n"
end
ensure_development_dependency() click to toggle source

Ensures that the {#gemspec_path} contains a development dependency on {GEM_NAME}.

Adds ‘spec.add_development_dependency ’metasploit_version’, ‘~> <semantic version requirement>’‘ if {#gemspec_path} does not have such an entry. Otherwise, updates the `<semantic version requirement>` to match this version of `metasploit-version`.

@return [void] @raise (see gemspec_path)

# File lib/metasploit/version/cli.rb, line 132
def ensure_development_dependency
  path = gemspec_path
  gem_specification = Gem::Specification.load(path)

  metasploit_version = gem_specification.dependencies.find { |dependency|
    dependency.name == GEM_NAME
  }

  lines = []

  if metasploit_version
    if metasploit_version.requirements_list.include? '>= 0'
      shell.say "Adding #{GEM_NAME} as a development dependency to "
    else
      shell.say "Updating #{GEM_NAME} requirements in "
    end

    shell.say path

    File.open(path) do |f|
      f.each_line do |line|
        match = line.match(DEVELOPMENT_DEPENDENCY_REGEXP)

        if match
          lines << development_dependency_line
        else
          lines << line
        end
      end
    end
  else
    end_index = nil
    lines = []

    open(path) do |f|
      line_index = 0

      f.each_line do |line|
        lines << line

        if line =~ /^\s*end\s*$/
          end_index = line_index
        end

        line_index += 1
      end
    end

    lines.insert(end_index, development_dependency_line)
  end

  File.open(path, 'w') do |f|
    lines.each do |line|
      f.write(line)
    end
  end
end
gemspec_path() click to toggle source

The name of the gemspec in the current working directory.

@return [String] relative path to the current working directory’s gemspec. @raise [SystemExit] if no gemspec is found

# File lib/metasploit/version/cli.rb, line 194
def gemspec_path
  unless instance_variable_defined? :@gemspec
    path = "#{name}.gemspec"

    unless File.exist?(path)
      shell.say 'No gemspec found'
      exit 1
    end

    @gemspec_path = path
  end

  @gemspec_path
end
github_url() click to toggle source

The URL of the github repository. Used to calculate the fork and issues URL in ‘CONTRIBUTING.md`.

@return [String] https url to github repository

# File lib/metasploit/version/cli.rb, line 212
def github_url
  @github_url ||= "https://github.com/#{options[:github_owner]}/#{name}"
end
install_bundle() click to toggle source

‘bundle install` if the :bundle_install options is `true`

@return [void]

# File lib/metasploit/version/cli.rb, line 219
def install_bundle
  if options[:bundle_install]
    system('bundle', 'install')
  end
end
name() click to toggle source

The name of the gem.

@return [String] name of the gem. Assumed to be the name of the pwd as it should match the repository name.

# File lib/metasploit/version/cli.rb, line 228
def name
  @name ||= File.basename(Dir.pwd)
end
namespace_name() click to toggle source

The fully-qualified namespace for the gem.

@param [String]

# File lib/metasploit/version/cli.rb, line 235
def namespace_name
  @namespace_name ||= namespaces.join('::')
end
namespaced_path() click to toggle source

The relative path of the gem under ‘lib`.

@return [String] Format of ‘[<parent>/]*<child>`

# File lib/metasploit/version/cli.rb, line 262
def namespaced_path
  @namespaced_path ||= name.tr('-', '/')
end
namespaces() click to toggle source

List of ‘Module#name`s making up the {#namespace_name the fully-qualifed namespace for the gem}.

@return [Array<String>]

# File lib/metasploit/version/cli.rb, line 242
def namespaces
  unless instance_variable_defined? :@namespaces
    underscored_words = name.split('_')
    capitalized_underscored_words = underscored_words.map { |underscored_word|
      capitalize(underscored_word)
    }
    capitalized_hyphenated_name = capitalized_underscored_words.join
    hyphenated_words = capitalized_hyphenated_name.split('-')

    @namespaces = hyphenated_words.map { |hyphenated_word|
      capitalize(hyphenated_word)
    }
  end

  @namespaces
end
prerelease() click to toggle source

The prerelease version.

@return [nil] if on master or HEAD @return [String] if on a branch

# File lib/metasploit/version/cli.rb, line 270
def prerelease
  unless instance_variable_defined? :@prerelease
    branch = Metasploit::Version::Branch.current
    parsed = Metasploit::Version::Branch.parse(branch)

    if parsed.is_a? Hash
      prerelease = parsed[:prerelease]

      if prerelease
        @prerelease = prerelease
      end
    end
  end

  @prerelease
end
setup_rspec() click to toggle source

Generates ‘.rspec`, `Rakefile`, `version_spec.rb`, `<namespace>_spec.rb` and `spec/spec_helper.rb`

@return [void]

# File lib/metasploit/version/cli.rb, line 290
def setup_rspec
  template('.rspec.tt', '.rspec')
  template('Rakefile.tt', 'Rakefile')
  template('spec/lib/versioned/version_spec.rb.tt', "spec/#{version_path.sub(/\.rb$/, '_spec.rb')}")
  template('spec/lib/versioned_spec.rb.tt', "spec/lib/#{namespaced_path}_spec.rb")
  template('spec/spec_helper.rb.tt', 'spec/spec_helper.rb')
end
version_path() click to toggle source

Path to the ‘version.rb` for the gem.

@return [String]

# File lib/metasploit/version/cli.rb, line 301
def version_path
  @version_path ||= "lib/#{namespaced_path}/version.rb"
end
version_requirement() click to toggle source

The version requirement on the ‘metasploit-version` development dependency in {#development_dependency_line}.

@return [String]

# File lib/metasploit/version/cli.rb, line 308
def version_requirement
  if defined? Metasploit::Version::Version::PRERELEASE
    # require exactly this pre-release in case there are multiple prereleases for the same
    # version number due to parallel branches.
    "= #{Metasploit::Version::GEM_VERSION}"
  elsif Metasploit::Version::Version::MAJOR < 1
    # can only allow the PATCH to wiggle pre-1.0.0
    "~> #{Metasploit::Version::Version::MAJOR}.#{Metasploit::Version::Version::MINOR}.#{Metasploit::Version::Version::PATCH}"
  else
    # can allow the MINOR to wiggle 1.0.0+
    "~> #{Metasploit::Version::Version::MAJOR}.#{Metasploit::Version::Version::MINOR}"
  end
end