fpm-cookery 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # v0.4.0 (2011-10-28)
2
+ * Add svn source handler. (lusis)
3
+ * Framework for alternate source handlers. (lusis)
4
+ * Add .zip support to the curl source handler.
5
+ * Detect package target based on the platform.
6
+ * Allow platform specific options. (like dependencies) (lusis)
7
+ * Add platform (operating system) detection. (lusis)
8
+
1
9
  # v0.3.0 (2011-10-25)
2
10
  * Select vendor string delimiter based on the package target. (lusis)
3
11
  * Add pre/post install/uninstall script support. (lusis)
data/fpm-cookery.gemspec CHANGED
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency "minitest"
23
23
  s.add_development_dependency "rake"
24
24
  s.add_runtime_dependency "fpm"
25
+ s.add_runtime_dependency "facter"
25
26
  end
@@ -21,6 +21,11 @@ module FPM
21
21
  @target = o
22
22
  end
23
23
 
24
+ options.on("-p PLATFORM", "--platform PLATFORM",
25
+ "Set the target platform. (centos, ubuntu, debian)") do |o|
26
+ @platform = o
27
+ end
28
+
24
29
  # Parse flags and such, remainder is all non-option args.
25
30
  remainder = options.parse(argv)
26
31
 
@@ -55,17 +60,28 @@ module FPM
55
60
  exit 1
56
61
  end
57
62
 
58
- if @target.nil?
59
- # TODO(sissel): Detect platform, try to guess @target?
60
- @target = "deb"
61
- puts "No --target given, assuming #{@target}"
62
- end
63
-
64
63
  # Default action is "package"
65
64
  if @actions.empty?
66
65
  @actions = ["package"]
67
66
  puts "No actions given, assuming 'package'"
68
67
  end
68
+
69
+ # Override the detected platform.
70
+ if @platform
71
+ FPM::Cookery::Facts.platform = @platform
72
+ end
73
+
74
+ if @target
75
+ FPM::Cookery::Facts.target = @target
76
+ end
77
+
78
+ if FPM::Cookery::Facts.target.nil?
79
+ STDERR.puts "No target given and we're unable to detect your platform"
80
+ exit 1
81
+ end
82
+
83
+ puts "Platform: #{FPM::Cookery::Facts.platform}"
84
+ puts "Target: #{FPM::Cookery::Facts.target}"
69
85
  end
70
86
 
71
87
  def run
@@ -75,7 +91,7 @@ module FPM
75
91
 
76
92
  FPM::Cookery::Book.load_recipe(@filename) do |recipe|
77
93
  packager = FPM::Cookery::Packager.new(recipe)
78
- packager.target = @target
94
+ packager.target = FPM::Cookery::Facts.target.to_s
79
95
 
80
96
  @actions.each do |action|
81
97
  case action
@@ -0,0 +1,30 @@
1
+ require 'facter'
2
+
3
+ module FPM
4
+ module Cookery
5
+ class Facts
6
+ def self.platform
7
+ @platform ||= Facter.fact(:operatingsystem).value.downcase.to_sym
8
+ end
9
+
10
+ def self.platform=(value)
11
+ @platform = value.downcase.to_sym
12
+ end
13
+
14
+ def self.target
15
+ @target ||= case platform
16
+ when :centos, :redhat, :fedora then :rpm
17
+ when :debian, :ubuntu then :deb
18
+ end
19
+ end
20
+
21
+ def self.target=(value)
22
+ @target = value.to_sym
23
+ end
24
+
25
+ def self.reset!
26
+ instance_variables.each {|v| instance_variable_set(v, nil) }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -42,25 +42,27 @@ module FPM
42
42
  Dir.chdir(recipe.cachedir) do
43
43
  source.fetch
44
44
 
45
- SourceIntegrityCheck.new(recipe).tap do |check|
46
- if check.checksum_missing?
47
- STDERR.puts <<-__WARN
48
- WARNING: Recipe does not provide a checksum. (sha256, sha1 or md5)
49
- ------------------------------------------------------------------
50
- Digest: #{check.digest}
51
- Checksum: #{check.checksum_actual}
52
- Filename: #{check.filename}
53
- __WARN
54
- elsif check.error?
55
- STDERR.puts <<-__ERROR
56
- ERROR: Integrity check failed!
57
- ------------------------------
58
- Digest: #{check.digest}
59
- Checksum expected: #{check.checksum_expected}
60
- Checksum actual: #{check.checksum_actual}
61
- Filename: #{check.filename}
62
- __ERROR
63
- exit 1
45
+ if source.checksum?
46
+ SourceIntegrityCheck.new(recipe).tap do |check|
47
+ if check.checksum_missing?
48
+ STDERR.puts <<-__WARN
49
+ WARNING: Recipe does not provide a checksum. (sha256, sha1 or md5)
50
+ ------------------------------------------------------------------
51
+ Digest: #{check.digest}
52
+ Checksum: #{check.checksum_actual}
53
+ Filename: #{check.filename}
54
+ __WARN
55
+ elsif check.error?
56
+ STDERR.puts <<-__ERROR
57
+ ERROR: Integrity check failed!
58
+ ------------------------------
59
+ Digest: #{check.digest}
60
+ Checksum expected: #{check.checksum_expected}
61
+ Checksum actual: #{check.checksum_actual}
62
+ Filename: #{check.filename}
63
+ __ERROR
64
+ exit 1
65
+ end
64
66
  end
65
67
  end
66
68
  end
@@ -1,5 +1,6 @@
1
1
  require 'forwardable'
2
2
  require 'fileutils'
3
+ require 'fpm/cookery/facts'
3
4
  require 'fpm/cookery/source_handler'
4
5
  require 'fpm/cookery/utils'
5
6
  require 'fpm/cookery/path_helper'
@@ -25,6 +26,10 @@ module FPM
25
26
  end
26
27
  end
27
28
 
29
+ def self.platforms(valid_platforms)
30
+ Array(valid_platforms).member?(self.platform) and block_given? ? yield : false
31
+ end
32
+
28
33
  def self.attr_rw_list(*attrs)
29
34
  attrs.each do |attr|
30
35
  class_eval %Q{
@@ -57,6 +62,10 @@ module FPM
57
62
  @spec = spec
58
63
  end
59
64
  alias_method :url, :source
65
+
66
+ def platform
67
+ FPM::Cookery::Facts.platform
68
+ end
60
69
  end
61
70
 
62
71
  def source
@@ -4,6 +4,10 @@ module FPM
4
4
  module Cookery
5
5
  class SourceHandler
6
6
  class Curl < FPM::Cookery::SourceHandler::Template
7
+
8
+ NAME = :curl
9
+ CHECKSUM = true
10
+
7
11
  def fetch
8
12
  unless local_path.exist?
9
13
  Dir.chdir(cachedir) do
@@ -18,6 +22,8 @@ module FPM
18
22
  case local_path.extname
19
23
  when '.bz2', '.gz', '.tgz'
20
24
  safesystem('tar', 'xf', local_path)
25
+ when '.zip'
26
+ safesystem('unzip', '-d', local_path.basename('.zip'), local_path)
21
27
  end
22
28
  end
23
29
  extracted_source
@@ -0,0 +1,54 @@
1
+ require 'fpm/cookery/source_handler/template'
2
+
3
+ module FPM
4
+ module Cookery
5
+ class SourceHandler
6
+ class Svn < FPM::Cookery::SourceHandler::Template
7
+
8
+ CHECKSUM = false
9
+ NAME = :svn
10
+
11
+ def fetch
12
+ # TODO(lusis) - implement some caching using 'svn info'?
13
+ Dir.chdir(cachedir) do
14
+ svn(url, local_path)
15
+ end
16
+ local_path
17
+ end
18
+
19
+ def extract
20
+ Dir.chdir(builddir) do
21
+ safesystem('cp', '-Rp', local_path, '.')
22
+ end
23
+ extracted_source
24
+ end
25
+
26
+ private
27
+ def svn(url, path)
28
+ @options.has_key?(:revision) ? revision=@options[:revision] : revision='HEAD'
29
+ safesystem('svn', 'export', '--force', '-q', '-r', revision, url, path)
30
+ end
31
+
32
+ def extracted_source
33
+ entries = Dir['*'].select {|dir| File.directory?(dir) }
34
+
35
+ case entries.size
36
+ when 0
37
+ raise "Empty checkout! (#{local_path})"
38
+ when 1
39
+ entries.first
40
+ else
41
+ ext = Path.new(url).extname
42
+ dir = local_path.basename(ext)
43
+
44
+ if File.exist?(dir)
45
+ dir
46
+ else
47
+ raise "Could not find source directory for #{local_path.basename}"
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -6,13 +6,18 @@ module FPM
6
6
  class Template
7
7
  include FPM::Cookery::Utils
8
8
 
9
- attr_reader :url, :options, :cachedir, :builddir
9
+ NAME = :template
10
+ CHECKSUM = true
11
+
12
+ attr_reader :url, :options, :cachedir, :builddir, :has_checksum, :name
10
13
 
11
14
  def initialize(source_url, options, cachedir, builddir)
12
15
  @url = source_url
13
16
  @options = options
14
17
  @cachedir = cachedir
15
18
  @builddir = builddir
19
+ @has_checksum = self.class::CHECKSUM
20
+ @name = self.class::NAME
16
21
  end
17
22
 
18
23
  def fetch
@@ -23,6 +28,10 @@ module FPM
23
28
  raise "#{self}#extract not implemented!"
24
29
  end
25
30
 
31
+ def checksum?
32
+ @has_checksum
33
+ end
34
+
26
35
  def local_path
27
36
  @local_path ||= cachedir/(options[:as] || File.basename(url))
28
37
  end
@@ -1,26 +1,44 @@
1
1
  require 'forwardable'
2
2
  require 'fpm/cookery/source_handler/curl'
3
+ require 'fpm/cookery/source_handler/svn'
3
4
 
4
5
  module FPM
5
6
  module Cookery
6
7
  class SourceHandler
8
+ DEFAULT_HANDLER = :curl
9
+
7
10
  extend Forwardable
8
- def_delegators :@handler, :fetch, :extract, :local_path
11
+ def_delegators :@handler, :fetch, :extract, :local_path, :checksum?
9
12
 
10
13
  def initialize(source_url, options, cachedir, builddir)
14
+ # The reason for these checks is related to the test cases
15
+ # Test cases for individual recipe attributes
16
+ # are not setting spec before hand (due to delegation chain?)
17
+ # Additionally, one test actually has options being sent as a String
18
+ if ( options.nil? || options.class == String || options.has_key?(:with) == false)
19
+ @source_provider = DEFAULT_HANDLER
20
+ else
21
+ @source_provider = options[:with]
22
+ end
11
23
  @source_url = source_url
12
24
  @options = options
13
25
  @cachedir = cachedir
14
26
  @builddir = builddir
15
- @handler = get_source_handler
27
+ @handler = get_source_handler(@source_provider)
16
28
  end
17
29
 
18
30
  private
19
- def get_source_handler
20
- case @source_url.to_s
21
- when 'NONE YET'
22
- else
23
- SourceHandler::Curl.new(@source_url, @options, @cachedir, @builddir)
31
+ def get_source_handler(provider)
32
+ klass = handler_to_class(provider)
33
+ klass.new(@source_url, @options, @cachedir, @builddir)
34
+ end
35
+
36
+ def handler_to_class(provider)
37
+ begin
38
+ self.class.const_get(provider.to_s.capitalize)
39
+ rescue NameError
40
+ STDERR.puts "Specified provider #{provider} does not exist."
41
+ exit(1)
24
42
  end
25
43
  end
26
44
  end
@@ -1,5 +1,5 @@
1
1
  module FPM
2
2
  module Cookery
3
- VERSION = '0.3.0'
3
+ VERSION = '0.4.0'
4
4
  end
5
5
  end
@@ -1,10 +1,13 @@
1
1
  class Redis < FPM::Cookery::Recipe
2
2
  homepage 'http://redis.io'
3
- source 'http://redis.googlecode.com/files/redis-2.2.5.tar.gz'
4
- md5 'fe6395bbd2cadc45f4f20f6bbe05ed09'
3
+ # different source methods
4
+ #source 'https://github.com/antirez/redis/trunk', :with => :svn
5
+ #source 'https://github.com/antirez/redis/trunk', :with => :svn, :revision => '2400'
6
+ source 'http://redis.googlecode.com/files/redis-2.4.2.tar.gz'
7
+ md5 'c4b0b5e4953a11a503cb54cf6b09670e'
5
8
 
6
9
  name 'redis-server'
7
- version '2.2.5'
10
+ version '2.4.2'
8
11
  # revision '0' # => redis-server-2.2.5+fpm1
9
12
 
10
13
  description 'An advanced key-value store.'
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+ require 'ostruct'
3
+ require 'fpm/cookery/facts'
4
+
5
+ describe "Facts" do
6
+ before do
7
+ FPM::Cookery::Facts.reset!
8
+ end
9
+
10
+ describe "platform" do
11
+ before do
12
+ Facter.class_eval do
13
+ def self.fact(v)
14
+ v == :operatingsystem ? OpenStruct.new(:value => 'CentOS') : nil
15
+ end
16
+ end
17
+ end
18
+
19
+ it "is using Facter to autodetect the platform" do
20
+ FPM::Cookery::Facts.platform.must_equal :centos
21
+ end
22
+
23
+ it "can be set" do
24
+ FPM::Cookery::Facts.platform = 'CentOS'
25
+ FPM::Cookery::Facts.platform.must_equal :centos
26
+ end
27
+ end
28
+
29
+ describe "target" do
30
+ describe "with platform CentOS" do
31
+ it "returns rpm" do
32
+ FPM::Cookery::Facts.platform = 'CentOS'
33
+ FPM::Cookery::Facts.target.must_equal :rpm
34
+ end
35
+ end
36
+
37
+ describe "with platform RedHat" do
38
+ it "returns rpm" do
39
+ FPM::Cookery::Facts.platform = 'RedHat'
40
+ FPM::Cookery::Facts.target.must_equal :rpm
41
+ end
42
+ end
43
+
44
+ describe "with platform Fedora" do
45
+ it "returns rpm" do
46
+ FPM::Cookery::Facts.platform = 'Fedora'
47
+ FPM::Cookery::Facts.target.must_equal :rpm
48
+ end
49
+ end
50
+
51
+ describe "with platform Debian" do
52
+ it "returns rpm" do
53
+ FPM::Cookery::Facts.platform = 'Debian'
54
+ FPM::Cookery::Facts.target.must_equal :deb
55
+ end
56
+ end
57
+
58
+ describe "with platform Ubuntu" do
59
+ it "returns rpm" do
60
+ FPM::Cookery::Facts.platform = 'Ubuntu'
61
+ FPM::Cookery::Facts.target.must_equal :deb
62
+ end
63
+ end
64
+
65
+ describe "with an unknown platform" do
66
+ it "returns nil" do
67
+ FPM::Cookery::Facts.platform = '___X___'
68
+ FPM::Cookery::Facts.target.must_equal nil
69
+ end
70
+ end
71
+
72
+ it "can be set" do
73
+ FPM::Cookery::Facts.target = 'rpm'
74
+ FPM::Cookery::Facts.target.must_equal :rpm
75
+ end
76
+ end
77
+ end
data/spec/recipe_spec.rb CHANGED
@@ -2,6 +2,8 @@ require 'spec_helper'
2
2
  require 'fpm/cookery/recipe'
3
3
 
4
4
  class TestRecipe < FPM::Cookery::Recipe
5
+ NAME = :test_recipe
6
+ CHECKSUM = true
5
7
  end
6
8
 
7
9
  describe "Recipe" do
@@ -72,6 +74,8 @@ describe "Recipe" do
72
74
  spec_recipe_attribute(:name, 'redis')
73
75
  spec_recipe_attribute(:revision, 12)
74
76
  spec_recipe_attribute(:section, 'lang')
77
+ # NOTE(lusis)
78
+ # see comment in `SourceHandler#initialize` r.e. options as `String`
75
79
  spec_recipe_attribute(:spec, {:foo => true})
76
80
  spec_recipe_attribute(:vendor, 'myvendor')
77
81
  spec_recipe_attribute(:version, '1.2')
@@ -174,6 +178,56 @@ describe "Recipe" do
174
178
  end
175
179
  end
176
180
 
181
+ describe ".platforms" do
182
+ describe "with a list of platforms" do
183
+ it "allows platform specific settings" do
184
+ klass.class_eval do
185
+ def self.platform; :ubuntu; end
186
+
187
+ vendor 'a'
188
+
189
+ platforms [:centos, :ubuntu] do
190
+ vendor 'b'
191
+ end
192
+ end
193
+
194
+ klass.new(__FILE__).vendor.must_equal 'b'
195
+ end
196
+ end
197
+
198
+ describe "with a single platform" do
199
+ it "allows platform specific settings" do
200
+ klass.class_eval do
201
+ def self.platform; :ubuntu; end
202
+
203
+ vendor 'a'
204
+
205
+ platforms :ubuntu do
206
+ vendor 'b'
207
+ end
208
+ end
209
+
210
+ klass.new(__FILE__).vendor.must_equal 'b'
211
+ end
212
+ end
213
+
214
+ describe "without a matching platform" do
215
+ it "does not set platform specific stuff" do
216
+ klass.class_eval do
217
+ def self.platform; :centos; end
218
+
219
+ vendor 'a'
220
+
221
+ platforms :ubuntu do
222
+ vendor 'b'
223
+ end
224
+ end
225
+
226
+ klass.new(__FILE__).vendor.must_equal 'a'
227
+ end
228
+ end
229
+ end
230
+
177
231
 
178
232
  #############################################################################
179
233
  # Directories
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fpm-cookery
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-25 00:00:00.000000000 Z
12
+ date: 2011-10-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fpm
16
- requirement: &71291120 !ruby/object:Gem::Requirement
16
+ requirement: &84112030 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *71291120
24
+ version_requirements: *84112030
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: minitest
27
- requirement: &71290880 !ruby/object:Gem::Requirement
27
+ requirement: &84111800 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *71290880
35
+ version_requirements: *84111800
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &71290650 !ruby/object:Gem::Requirement
38
+ requirement: &84127950 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *71290650
46
+ version_requirements: *84127950
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: fpm
49
- requirement: &71290430 !ruby/object:Gem::Requirement
49
+ requirement: &84127720 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,18 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *71290430
57
+ version_requirements: *84127720
58
+ - !ruby/object:Gem::Dependency
59
+ name: facter
60
+ requirement: &84127470 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *84127470
58
69
  description: A tool for building software packages with fpm.
59
70
  email:
60
71
  - bernd@tuneafish.de
@@ -74,12 +85,14 @@ files:
74
85
  - lib/fpm/cookery/book.rb
75
86
  - lib/fpm/cookery/book_hook.rb
76
87
  - lib/fpm/cookery/cli.rb
88
+ - lib/fpm/cookery/facts.rb
77
89
  - lib/fpm/cookery/packager.rb
78
90
  - lib/fpm/cookery/path.rb
79
91
  - lib/fpm/cookery/path_helper.rb
80
92
  - lib/fpm/cookery/recipe.rb
81
93
  - lib/fpm/cookery/source_handler.rb
82
94
  - lib/fpm/cookery/source_handler/curl.rb
95
+ - lib/fpm/cookery/source_handler/svn.rb
83
96
  - lib/fpm/cookery/source_handler/template.rb
84
97
  - lib/fpm/cookery/source_integrity_check.rb
85
98
  - lib/fpm/cookery/utils.rb
@@ -87,6 +100,7 @@ files:
87
100
  - recipes/nodejs/recipe.rb
88
101
  - recipes/redis/recipe.rb
89
102
  - recipes/redis/redis-server.init.d
103
+ - spec/facts_spec.rb
90
104
  - spec/fixtures/test-source-1.0.tar.gz
91
105
  - spec/path_helper_spec.rb
92
106
  - spec/path_spec.rb