Class: Stove::Packager

Inherits:
Object
  • Object
show all
Defined in:
lib/stove/packager.rb

Constant Summary collapse

ACCEPTABLE_FILES =
[
  '.foodcritic',
  'README.*',
  'CHANGELOG.*',
  'CONTRIBUTING.md',
  'MAINTAINERS.md',
  'metadata.{json,rb}',
  'attributes/*.rb',
  'definitions/*.rb',
  'files/**/*',
  'libraries/**/*.rb',
  'providers/**/*.rb',
  'recipes/*.rb',
  'resources/**/*.rb',
  'templates/**/*',
].freeze
ACCEPTABLE_FILES_LIST =
ACCEPTABLE_FILES.join(',').freeze
TMP_FILES =
[
  /^(?:.*[\\\/])?\.[^\\\/]+\.sw[p-z]$/,
  /~$/,
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cookbook, extended_metadata = false) ⇒ Packager

Create a new packager instance.

Parameters:

  • the (Stove::Cookbook)

    cookbook to package

  • extended_metadata (true, false) (defaults to: false)

    include new extended metadata attributes



48
49
50
51
# File 'lib/stove/packager.rb', line 48

def initialize(cookbook,  = false)
  @cookbook = cookbook
  @extended_metadata = 
end

Instance Attribute Details

#cookbookObject (readonly)

The cookbook to package.



35
36
37
# File 'lib/stove/packager.rb', line 35

def cookbook
  @cookbook
end

#extended_metadatatrue, false (readonly)

Whether to include the new extended metadata attributes.

Returns:

  • (true, false)


40
41
42
# File 'lib/stove/packager.rb', line 40

def 
  @extended_metadata
end

Instance Method Details

#gzip(io) ⇒ IO

GZip the given IO object (like a File or StringIO).

Parameters:

  • io (IO)

    the io object to gzip

Returns:

  • (IO)

    the gzipped IO object



143
144
145
146
147
148
149
150
151
152
# File 'lib/stove/packager.rb', line 143

def gzip(io)
  gz = StringIO.new('')
  z = Zlib::GzipWriter.new(gz)
  z.write(io.string)
  z.close

  # z was closed to write the gzip footer, so
  # now we need a new StringIO
  StringIO.new(gz.string)
end

#packaging_slipHash<String, String>

A map from physical file path to tarball file path

Examples:

# Assuming +cookbook.name+ is 'apt'

{
  '/home/user/apt-cookbook/metadata.json' => 'apt/metadata.json',
  '/home/user/apt-cookbook/README.md' => 'apt/README.md'
}

Returns:

  • (Hash<String, String>)

    the map of file paths



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/stove/packager.rb', line 65

def packaging_slip
  root = File.expand_path(cookbook.path)
  path = File.join(root, "{#{ACCEPTABLE_FILES_LIST}}")

  Dir.glob(path, File::FNM_DOTMATCH)
    .reject { |path| %w(. ..).include?(File.basename(path)) }
    .reject { |path| TMP_FILES.any? { |regex| path.match(regex) } }
    .map    { |path| [path, path.sub(/^#{Regexp.escape(root)}/, cookbook.name)] }
    .reduce({}) do |map, (cookbook_file, tarball_file)|
      map[cookbook_file] = tarball_file
    map
  end
end

#tar(root, slip) ⇒ StringIO

Create a tar file from the given root and packaging slip

Parameters:

  • root (String)

    the root where the tar files are being created

  • slip (Hash<String, String>)

    the map from physical file path to tarball file path

Returns:

  • (StringIO)

    the io object that contains the tarball contents



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/stove/packager.rb', line 114

def tar(root, slip)
  io = StringIO.new('', 'r+b')
  Gem::Package::TarWriter.new(io) do |tar|
    slip.each do |original_file, tarball_file|
      mode = File.stat(original_file).mode

      if File.directory?(original_file)
        tar.mkdir(tarball_file, mode)
      else
        tar.add_file(tarball_file, mode) do |tf|
          File.open(original_file, 'rb') { |f| tf.write(f.read) }
        end
      end
    end
  end

  io.rewind
  io
end

#tarballObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/stove/packager.rb', line 79

def tarball
  # Generate the metadata.json on the fly
   = File.join(cookbook.path, 'metadata.json')
  json = JSON.fast_generate(cookbook..to_hash())
  File.open(, 'wb') { |f| f.write(json) }

  io  = tar(File.dirname(cookbook.path), packaging_slip)
  tgz = gzip(io)

  tempfile = Tempfile.new([cookbook.name, '.tar.gz'], Dir.tmpdir)
  tempfile.binmode

  while buffer = tgz.read(1024)
    tempfile.write(buffer)
  end

  tempfile.rewind
  tempfile
ensure
  if defined?() && File.exist?(File.join(cookbook.path, 'metadata.rb'))
    File.delete()
  end
end