Class: Berkshelf::CookbookStore

Inherits:
Object
  • Object
show all
Defined in:
lib/berkshelf/cookbook_store.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(storage_path) ⇒ CookbookStore

Create a new instance of CookbookStore with the given storage_path.

Parameters:

  • storage_path (String)

    local filesystem path to the location to be initialized as a CookbookStore.



45
46
47
48
# File 'lib/berkshelf/cookbook_store.rb', line 45

def initialize(storage_path)
  @storage_path = Pathname.new(storage_path)
  initialize_filesystem
end

Instance Attribute Details

#storage_pathString (readonly)

Returns filepath to where cookbooks are stored.

Returns:

  • (String)

    filepath to where cookbooks are stored



37
38
39
# File 'lib/berkshelf/cookbook_store.rb', line 37

def storage_path
  @storage_path
end

Class Method Details

.default_pathString

The default path to the cookbook store relative to the Berkshelf path.

Returns:



10
11
12
# File 'lib/berkshelf/cookbook_store.rb', line 10

def default_path
  File.join(Berkshelf.berkshelf_path, "cookbooks")
end

.import(name, version, path) ⇒ Berkshelf::CachedCookbook

Import a cookbook found on the local filesystem into the current instance of the cookbook store.

Parameters:

  • name (String)

    name of the cookbook

  • version (String)

    verison of the cookbook

  • path (String)

    location on disk of the cookbook

Returns:



30
31
32
# File 'lib/berkshelf/cookbook_store.rb', line 30

def import(name, version, path)
  instance.import(name, version, path)
end

.instanceBerkshelf::CookbookStore



15
16
17
# File 'lib/berkshelf/cookbook_store.rb', line 15

def instance
  @instance ||= new(default_path)
end

Instance Method Details

#clean!Object

Destroy the contents of the initialized storage path.



51
52
53
# File 'lib/berkshelf/cookbook_store.rb', line 51

def clean!
  FileUtils.rm_rf(Dir.glob("#{storage_path}/*"))
end

#cookbook(name, version) ⇒ Berkshelf::CachedCookbook?

Returns an instance of CachedCookbook representing the Cookbook of your given name and version.

Parameters:

  • name (String)

    name of the Cookbook you want to retrieve

  • version (String)

    version of the Cookbook you want to retrieve

Returns:



83
84
85
86
87
88
# File 'lib/berkshelf/cookbook_store.rb', line 83

def cookbook(name, version)
  path = cookbook_path(name, version)
  return nil unless path.cookbook?

  CachedCookbook.from_store_path(path)
end

#cookbook_path(name, version) ⇒ Pathname

Returns an expanded path to the location on disk where the Cookbook of the given name and version is located.

Parameters:

Returns:



143
144
145
# File 'lib/berkshelf/cookbook_store.rb', line 143

def cookbook_path(name, version)
  storage_path.join("#{name}-#{version}")
end

#cookbooks(filter = nil) ⇒ Array<Berkshelf::CachedCookbook>

Returns an array of the Cookbooks that have been cached to the storage_path of this instance of CookbookStore.

Parameters:

  • filter (String, Regexp) (defaults to: nil)

    return only the CachedCookbooks whose name match the given filter

Returns:



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/berkshelf/cookbook_store.rb', line 97

def cookbooks(filter = nil)
  skipped_cookbooks = []
  cookbooks = storage_path.children.collect do |path|
    begin
      Semverse::Version.split(File.basename(path).slice(CachedCookbook::DIRNAME_REGEXP, 2))
    rescue Semverse::InvalidVersionFormat
      # Skip cookbooks that were downloaded by an SCM location. These can not be considered
      # complete cookbooks.
      next
    end

    begin
      CachedCookbook.from_store_path(path)
    rescue Chef::Exceptions::MetadataNotValid
      # Skip cached cookbooks that do not have a name attribute.
      skipped_cookbooks << File.basename(path)
      next
    end
  end.compact

  if skipped_cookbooks.any?
    msg = "Skipping cookbooks #{skipped_cookbooks}. Berkshelf can only interact "
    msg << "with cookbooks which have defined the `name` attribute in their metadata.rb. If you "
    msg << "are the maintainer of any of the above cookbooks, please add the name attribute to "
    msg << "your cookbook. If you are not the maintainer, please file an issue or report the lack "
    msg << "of a name attribute as a bug.\n\n"
    msg << "You can remove each cookbook in #{skipped_cookbooks} from the Berkshelf shelf "
    msg << "by using the `berks shelf uninstall` command:\n\n"
    msg << "    $ berks shelf uninstall <name>"
    Berkshelf.log.warn msg
  end

  return cookbooks unless filter

  cookbooks.select do |cookbook|
    filter === cookbook.cookbook_name
  end
end

#import(name, version, path) ⇒ Berkshelf::CachedCookbook

Import a cookbook found on the local filesystem into this instance of the cookbook store.

Parameters:

  • name (String)

    name of the cookbook

  • version (String)

    verison of the cookbook

  • path (String)

    location on disk of the cookbook

Returns:



65
66
67
68
69
70
71
72
# File 'lib/berkshelf/cookbook_store.rb', line 65

def import(name, version, path)
  destination = cookbook_path(name, version)
  FileUtils.mv(path, destination)
  cookbook(name, version)
rescue
  FileUtils.rm_f(destination)
  raise
end

#initialize_filesystemObject



147
148
149
150
151
152
153
# File 'lib/berkshelf/cookbook_store.rb', line 147

def initialize_filesystem
  FileUtils.mkdir_p(storage_path, mode: 0755)

  unless File.writable?(storage_path)
    raise InsufficientPrivledges.new(storage_path)
  end
end

#satisfy(name, constraint) ⇒ Berkshelf::CachedCookbook?

Return a CachedCookbook matching the best solution for the given name and constraint. Nil is returned if no matching CachedCookbook is found.

Parameters:

  • name (#to_s)
  • constraint (Semverse::Constraint)

Returns:



162
163
164
165
166
167
168
169
170
171
# File 'lib/berkshelf/cookbook_store.rb', line 162

def satisfy(name, constraint)
  graph = Solve::Graph.new
  cookbooks(name).each { |cookbook| graph.artifact(name, cookbook.version) }

  name, version = Solve.it!(graph, [[name, constraint]], ENV["DEBUG_RESOLVER"] ? { ui: Berkshelf.ui } : {}).first

  cookbook(name, version)
rescue Solve::Errors::NoSolutionError
  nil
end