Class: FPM::Cookery::Packager

Inherits:
Object
  • Object
show all
Includes:
Utils
Defined in:
lib/fpm/cookery/packager.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(recipe, config = {}) ⇒ Packager

Returns a new instance of Packager.



19
20
21
22
# File 'lib/fpm/cookery/packager.rb', line 19

def initialize(recipe, config = {})
  @recipe = recipe
  @config = config
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



17
18
19
# File 'lib/fpm/cookery/packager.rb', line 17

def config
  @config
end

#recipeObject (readonly)

Returns the value of attribute recipe.



17
18
19
# File 'lib/fpm/cookery/packager.rb', line 17

def recipe
  @recipe
end

Instance Method Details

#add_scripts(recipe, input) ⇒ Object



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/fpm/cookery/packager.rb', line 177

def add_scripts(recipe, input)
  error = false

  # Map script names to fpm method names.
  script_map = {
    'pre_install' => :before_install,
    'post_install' => :after_install,
    'pre_uninstall' => :before_remove,
    'post_uninstall' => :after_remove
  }

  script_map.each do |script, fpm_script|
    unless recipe.send(script).nil?
      script_file = FPM::Cookery::Path.new(recipe.send(script))

      # If the script file is an absolute path, just use that path.
      # Otherwise consider the location relative to the recipe.
      unless script_file.absolute?
        script_file = File.expand_path("../#{script_file.to_s}", recipe.filename)
      end

      if File.exists?(script_file)
        input.scripts[fpm_script] = File.read(script_file.to_s)
      else
        Log.error "#{script} script '#{script_file}' is missing"
        error = true
      end
    end
  end

  exit(1) if error
end


118
119
120
# File 'lib/fpm/cookery/packager.rb', line 118

def build_cookie_name(name)
  (recipe.builddir/".build-cookie-#{name.gsub(/[^\w]/,'_')}").to_s
end

#build_package(recipe, config) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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/fpm/cookery/packager.rb', line 122

def build_package(recipe, config)
  recipe.pkgdir.mkdir
  Dir.chdir(recipe.pkgdir) do
    epoch, ver = recipe.version.split(':', 2)
    if ver.nil?
      ver, epoch = epoch, nil
    end

    # Build a version including vendor and revision.
    vendor = config[:vendor] || recipe.vendor
    vendor_rev = "#{vendor}#{recipe.revision}"
    case @target
    when "deb"
      vendor_delimiter = "+"
    when "rpm"
      vendor_delimiter = "."
    else
      vendor_delimiter = "-"
    end
    version = [ver, vendor_rev].join(vendor_delimiter)

    maintainer = recipe.maintainer || begin
      username = `git config --get user.name`.strip
      useremail = `git config --get user.email`.strip

      username && useremail ? "#{username} <#{useremail}>" : nil
    end

    input = FPM::Cookery::Package::Dir.new(recipe)

    input.version = version
    input.maintainer = maintainer
    input.epoch = epoch if epoch

    add_scripts(recipe, input)
    remove_excluded_files(recipe)

    output_class = FPM::Package.types[@target]

    output = input.convert(output_class)

    begin
      output.output(output.to_s)
    rescue FPM::Package::FileAlreadyExists
      Log.info "Removing existing package file: #{output.to_s}"
      FileUtils.rm_f(output.to_s)
      retry
    ensure
      input.cleanup if input
      output.cleanup if output
      Log.info "Created package: #{File.join(Dir.pwd, output.to_s)}"
    end
  end
end

#cleanupObject



29
30
31
32
33
34
35
# File 'lib/fpm/cookery/packager.rb', line 29

def cleanup
  Log.info "Cleanup!"
  # TODO(sissel): do some sanity checking to make sure we don't
  # accidentally rm -rf the wrong thing.
  FileUtils.rm_rf(recipe.builddir)
  FileUtils.rm_rf(recipe.destdir)
end

#dispenseObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/fpm/cookery/packager.rb', line 37

def dispense
  env = ENV.to_hash
  package_name = "#{recipe.name}-#{recipe.version}"
  platform = FPM::Cookery::Facts.platform
  target = FPM::Cookery::Facts.target

  Log.info "Starting package creation for #{package_name} (#{platform}, #{target})"
  Log.info ''

  # RecipeInspector.verify!(recipe)
  # DependencyInspector.verify!(recipe.depends, recipe.build_depends)

  recipe.installing = false

  source = recipe.source_handler

  recipe.cachedir.mkdir
  Dir.chdir(recipe.cachedir) do
    Log.info "Fetching source: #{source.source_url}"
    source.fetch

    if source.checksum?
      SourceIntegrityCheck.new(recipe).tap do |check|
        if check.checksum_missing?
          Log.warn 'Recipe does not provide a checksum. (sha256, sha1 or md5)'
          Log.puts <<-__WARN
  Digest:   #{check.digest}
  Checksum: #{check.checksum_actual}
  Filename: #{check.filename}

          __WARN
        elsif check.error?
          Log.error 'Integrity check failed!'
          Log.puts <<-__ERROR
  Digest:            #{check.digest}
  Checksum expected: #{check.checksum_expected}
  Checksum actual:   #{check.checksum_actual}
  Filename:          #{check.filename}

          __ERROR
          exit 1
        end
      end
    end
  end

  recipe.builddir.mkdir
  Dir.chdir(recipe.builddir) do
    extracted_source = source.extract

    Dir.chdir(extracted_source) do
      #Source::Patches.new(recipe.patches).apply!

      build_cookie = build_cookie_name(package_name)

      if File.exists?(build_cookie)
        Log.info 'Skipping build (`fpm-cook clean` to rebuild)'
      else
        Log.info "Building in #{File.expand_path(extracted_source)}"
        recipe.build and FileUtils.touch(build_cookie)
      end

      FileUtils.rm_rf(recipe.destdir)
      recipe.destdir.mkdir

      begin
        recipe.installing = true
        Log.info "Installing into #{recipe.destdir}"
        recipe.install
      ensure
        recipe.installing = false
      end
    end
  end

  build_package(recipe, config)
ensure
  # Make sure we reset the environment.
  ENV.replace(env)
end

#remove_excluded_files(recipe) ⇒ Object

Remove all excluded files from the destdir so they do not end up in the package.



212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/fpm/cookery/packager.rb', line 212

def remove_excluded_files(recipe)
  Dir.chdir(recipe.destdir.to_s) do
    Dir['**/*'].each do |file|
      recipe.exclude.each do |ex|
        if File.fnmatch(ex, file)
          Log.info "Exclude file: #{file}"
          FileUtils.rm_f(file)
        end
      end
    end
  end
end

#target=(target) ⇒ Object



24
25
26
27
# File 'lib/fpm/cookery/packager.rb', line 24

def target=(target)
  # TODO(sissel): do sanity checking
  @target = target
end