Class: Bolt::ModuleInstaller::Specs::GitSpec

Inherits:
Object
  • Object
show all
Defined in:
lib/bolt/module_installer/specs/git_spec.rb

Constant Summary collapse

NAME_REGEX =
%r{\A(?:[a-zA-Z0-9]+[-/])?(?<name>[a-z][a-z0-9_]*)\z}.freeze
REQUIRED_KEYS =
Set.new(%w[git ref]).freeze
KNOWN_KEYS =
Set.new(%w[git name ref resolve]).freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(init_hash) ⇒ GitSpec

Returns a new instance of GitSpec.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 20

def initialize(init_hash)
  @resolve    = init_hash.key?('resolve') ? init_hash['resolve'] : true
  @name       = parse_name(init_hash['name'])
  @git, @repo = parse_git(init_hash['git'])
  @ref        = init_hash['ref']
  @type       = :git

  if @name.nil? && @resolve == false
    raise Bolt::ValidationError,
          "Missing name for Git module specification: #{@git}. Git module specifications "\
          "must include a 'name' key when 'resolve' is false."
  end

  unless @resolve == true || @resolve == false
    raise Bolt::ValidationError,
          "Option 'resolve' for module spec #{@git} must be a Boolean"
  end
end

Instance Attribute Details

#gitObject (readonly)

Returns the value of attribute git.



18
19
20
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 18

def git
  @git
end

#refObject (readonly)

Returns the value of attribute ref.



18
19
20
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 18

def ref
  @ref
end

#resolveObject (readonly)

Returns the value of attribute resolve.



18
19
20
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 18

def resolve
  @resolve
end

#typeObject (readonly)

Returns the value of attribute type.



18
19
20
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 18

def type
  @type
end

Class Method Details

.implements?(hash) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 39

def self.implements?(hash)
  KNOWN_KEYS.superset?(hash.keys.to_set) && REQUIRED_KEYS.subset?(hash.keys.to_set)
end

Instance Method Details

#nameObject

Resolves the module’s title from the module metadata. This is lazily resolved since Bolt does not always need to know a Git module’s name.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 113

def name
  @name ||= begin
    url      = "https://raw.githubusercontent.com/#{@repo}/#{sha}/metadata.json"
    response = make_request(:Get, url)

    case response
    when Net::HTTPOK
      body = JSON.parse(response.body)

      unless body.key?('name')
        raise Bolt::Error.new(
          "Missing name in metadata.json at #{git}. This is not a valid module.",
          "bolt/missing-module-name-error"
        )
      end

      parse_name(body['name'])
    else
      raise Bolt::Error.new(
        "Missing metadata.json at #{git}. This is not a valid module.",
        "bolt/missing-module-metadata-error"
      )
    end
  end
end

#satisfied_by?(mod) ⇒ Boolean

Returns true if the specification is satisfied by the module.

Returns:

  • (Boolean)


78
79
80
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 78

def satisfied_by?(mod)
  @type == mod.type && @git == mod.git
end

#shaObject

Resolves the SHA for the specified ref. This is lazily resolved since Bolt does not always need to know a Git module’s SHA.



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 142

def sha
  @sha ||= begin
    url      = "https://api.github.com/repos/#{@repo}/commits/#{ref}"
    headers  = ENV['GITHUB_TOKEN'] ? { "Authorization" => "token #{ENV['GITHUB_TOKEN']}" } : {}
    response = make_request(:Get, url, headers)

    case response
    when Net::HTTPOK
      body = JSON.parse(response.body)
      body['sha']
    when Net::HTTPUnauthorized
      raise Bolt::Error.new(
        "Invalid token at GITHUB_TOKEN, unable to resolve git modules.",
        "bolt/invalid-git-token-error"
      )
    when Net::HTTPForbidden
      message = "GitHub API rate limit exceeded, unable to resolve git modules. "

      unless ENV['GITHUB_TOKEN']
        message += "To increase your rate limit, set the GITHUB_TOKEN environment "\
                  "variable with a GitHub personal access token."
      end

      raise Bolt::Error.new(message, 'bolt/github-api-rate-limit-error')
    when Net::HTTPNotFound
      raise Bolt::Error.new(invalid_git_msg(git), "bolt/missing-git-repository-error")
    else
      raise Bolt::Error.new(
        "Ref #{ref} at #{git} is not a commit, tag, or branch.",
        "bolt/invalid-git-ref-error"
      )
    end
  end
end

#to_hashObject

Returns a hash matching the module spec in bolt-project.yaml



84
85
86
87
88
89
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 84

def to_hash
  {
    'git' => @git,
    'ref' => @ref
  }
end

#to_resolver_moduleObject

Returns a PuppetfileResolver::Model::GitModule object for resolving.



101
102
103
104
105
106
107
108
# File 'lib/bolt/module_installer/specs/git_spec.rb', line 101

def to_resolver_module
  require 'puppetfile-resolver'

  PuppetfileResolver::Puppetfile::GitModule.new(name).tap do |mod|
    mod.remote = @git
    mod.ref    = sha
  end
end