fpm-cookery 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.autotest ADDED
@@ -0,0 +1,21 @@
1
+ require 'autotest/restart'
2
+
3
+ Autotest.add_hook :initialize do |at|
4
+ at.testlib = 'minitest/autorun'
5
+ at.order = :natural
6
+ at.libs = '.:lib:spec'
7
+
8
+ at.clear_mappings
9
+
10
+ at.add_mapping(%r{^spec/.*_spec\.rb$}) do |filename, _|
11
+ filename
12
+ end
13
+
14
+ at.add_mapping(%r{^lib/(.*)\.rb$}) do |_, m|
15
+ ["spec/#{m[1].gsub('fpm/cookery/', '')}_spec.rb"]
16
+ end
17
+
18
+ at.add_mapping(%r{^spec/spec_helper\.rb$}) do
19
+ at.files_matching %r{^spec/.*_spec\.rb$}
20
+ end
21
+ end
data/CHANGELOG.md CHANGED
@@ -1,2 +1,6 @@
1
- # v0.0.1
1
+ # v0.1.0 (2011-10-18)
2
+ * Add `with_trueprefix` path helper.
3
+ * Add and enable source integrity check.
4
+
5
+ # v0.0.1 (2011-10-11)
2
6
  * Initial gem release.
data/README.md CHANGED
@@ -64,21 +64,18 @@ __fpm-cookery__ is my attempt to build such a tool.
64
64
 
65
65
  ## Getting Started
66
66
 
67
- Since there is no gem available yet, you have to clone the repository to
68
- your local machine and run the following to build a recipe.
67
+ __fpm-cookery__ is available as a gem.
69
68
 
70
- $ ruby bin/fpm-cook recipes/redis/recipe.rb clean
71
- $ ruby bin/fpm-cook recipes/redis/recipe.rb
69
+ $ gem install fpm-cookery
72
70
 
73
- Or change into the recipe directory.
71
+ Create a recipe directory or change into an existing recipe tree.
74
72
 
75
- $ export PATH="$PWD/bin:$PATH"
76
73
  $ cd recipes/redis
77
74
  $ fpm-cook clean
78
75
  $ fpm-cook
79
76
 
80
- You can run the included test suite with `rake test`. This needs the __rake__
81
- and __minitest__ gems.
77
+ You can install the development dependencies with `bundle install` and run
78
+ the included test suite with `rake test`.
82
79
 
83
80
  ## Status
84
81
 
@@ -140,7 +137,6 @@ The following is an example recipe. I have some more in my recipe collection
140
137
  * No support for patches yet.
141
138
  * Only simple source/url types (via curl) for now.
142
139
  * No real logging output yet.
143
- * No gem on rubygems.org yet.
144
140
  * Pretty new and not well tested.
145
141
 
146
142
  ## Credits
data/fpm-cookery.gemspec CHANGED
@@ -20,5 +20,6 @@ Gem::Specification.new do |s|
20
20
 
21
21
  s.add_development_dependency "fpm"
22
22
  s.add_development_dependency "minitest"
23
+ s.add_development_dependency "rake"
23
24
  s.add_runtime_dependency "fpm"
24
25
  end
@@ -2,6 +2,7 @@
2
2
  #require 'fpm/cookery/recipe_inspector'
3
3
  #require 'fpm/cookery/dependency_inspector'
4
4
  require 'fpm/cookery/utils'
5
+ require 'fpm/cookery/source_integrity_check'
5
6
 
6
7
  module FPM
7
8
  module Cookery
@@ -34,11 +35,27 @@ module FPM
34
35
  Dir.chdir(recipe.cachedir) do
35
36
  source.fetch
36
37
 
37
- #check = Source::IntegrityCheck.new(source.filename, recipe.md5, Digest::MD5)
38
-
39
- #if check.error?
40
- # check.actual, check.expected, check.filename, check.digest
41
- #end
38
+ SourceIntegrityCheck.new(recipe).tap do |check|
39
+ if check.checksum_missing?
40
+ STDERR.puts <<-__WARN
41
+ WARNING: Recipe does not provide a checksum. (sha256, sha1 or md5)
42
+ ------------------------------------------------------------------
43
+ Digest: #{check.digest}
44
+ Checksum: #{check.checksum_actual}
45
+ Filename: #{check.filename}
46
+ __WARN
47
+ elsif check.error?
48
+ STDERR.puts <<-__ERROR
49
+ ERROR: Integrity check failed!
50
+ ------------------------------
51
+ Digest: #{check.digest}
52
+ Checksum expected: #{check.checksum_expected}
53
+ Checksum actual: #{check.checksum_actual}
54
+ Filename: #{check.filename}
55
+ __ERROR
56
+ exit 1
57
+ end
58
+ end
42
59
  end
43
60
 
44
61
  recipe.builddir.mkdir
@@ -23,7 +23,7 @@ module FPM
23
23
  end
24
24
 
25
25
  def bin(path = nil) prefix/'bin'/path end
26
- def doc(path = nil) prefix/'share/doc'/path/name end
26
+ def doc(path = nil) prefix/'share/doc'/path end
27
27
  def include(path = nil) prefix/'include'/path end
28
28
  def info(path = nil) prefix/'share/info'/path end
29
29
  def lib(path = nil) prefix/'lib'/path end
@@ -40,6 +40,21 @@ module FPM
40
40
  def sbin(path = nil) prefix/'sbin'/path end
41
41
  def share(path = nil) prefix/'share'/path end
42
42
 
43
+ # Return real paths for the scope of the given block.
44
+ #
45
+ # prefix('usr') # => /../software/tmp-dest/usr
46
+ #
47
+ # with_trueprefix do
48
+ # prefix('usr') # => /usr
49
+ # end
50
+ def with_trueprefix
51
+ old_value = installing
52
+ self.installing = false
53
+ yield
54
+ ensure
55
+ self.installing = old_value
56
+ end
57
+
43
58
  private
44
59
  def current_pathname_for(dir)
45
60
  installing? ? destdir/dir : Path.new("/#{dir}")
@@ -1,3 +1,4 @@
1
+ require 'forwardable'
1
2
  require 'fileutils'
2
3
  require 'fpm/cookery/source_handler'
3
4
  require 'fpm/cookery/utils'
@@ -43,7 +44,7 @@ module FPM
43
44
  end
44
45
 
45
46
  attr_rw :arch, :description, :homepage, :maintainer, :md5, :name,
46
- :revision, :section, :spec, :vendor, :version
47
+ :revision, :section, :sha1, :sha256, :spec, :vendor, :version
47
48
 
48
49
  attr_rw_list :build_depends, :config_files, :conflicts, :depends,
49
50
  :exclude, :patches, :provides, :replaces
@@ -72,6 +73,9 @@ module FPM
72
73
 
73
74
  attr_reader :filename, :source_handler
74
75
 
76
+ extend Forwardable
77
+ def_delegator :@source_handler, :local_path
78
+
75
79
  def workdir=(value) @workdir = Path.new(value) end
76
80
  def destdir=(value) @destdir = Path.new(value) end
77
81
  def builddir=(value) @builddir = Path.new(value) end
@@ -0,0 +1,72 @@
1
+ require 'digest/sha1'
2
+
3
+ module FPM
4
+ module Cookery
5
+ class SourceIntegrityCheck
6
+ attr_reader :checksum_expected, :checksum_actual, :filename, :digest
7
+
8
+ def initialize(recipe)
9
+ @recipe = recipe
10
+ @error = false
11
+ @filename = recipe.local_path
12
+ @digest = nil
13
+ @checksum_expected = nil
14
+ @checksum_actual = nil
15
+ verify!
16
+ end
17
+
18
+ def error?
19
+ @error
20
+ end
21
+
22
+ def checksum_missing?
23
+ checksum_expected.nil?
24
+ end
25
+
26
+ private
27
+ def verify!
28
+ digest, checksum = get_checksum
29
+
30
+ @digest = digest
31
+ @checksum_expected = checksum
32
+ @checksum_actual = build_checksum(digest)
33
+
34
+ unless digest
35
+ @error = true
36
+ @digest = :sha256
37
+ @checksum_actual = build_checksum(@digest)
38
+ end
39
+
40
+ if @checksum_expected.to_s != @checksum_actual.to_s
41
+ @error = true
42
+ end
43
+ end
44
+
45
+ def get_checksum
46
+ type = [:sha256, :sha1, :md5].find do |digest|
47
+ @recipe.respond_to?(digest) and
48
+ @recipe.send(digest) and
49
+ !@recipe.send(digest).empty?
50
+ end
51
+
52
+ [type, @recipe.send(type)]
53
+ rescue TypeError
54
+ [nil, nil]
55
+ end
56
+
57
+ def build_checksum(type)
58
+ return unless type
59
+
60
+ digest = Digest.const_get(type.to_s.upcase).new
61
+
62
+ File.open(@recipe.local_path, 'r') do |file|
63
+ while chunk = file.read(4096)
64
+ digest.update(chunk)
65
+ end
66
+ end
67
+
68
+ digest.hexdigest
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,5 +1,5 @@
1
1
  module FPM
2
2
  module Cookery
3
- VERSION = '0.0.1'
3
+ VERSION = '0.1.0'
4
4
  end
5
5
  end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+ require 'fpm/cookery/path_helper'
3
+
4
+ describe "PathHelper" do
5
+ class PathTest
6
+ include FPM::Cookery::PathHelper
7
+
8
+ def destdir; FPM::Cookery::Path.new('/tmp/dest') end
9
+ end
10
+
11
+ let(:helper) { PathTest.new }
12
+
13
+ describe "path helper methods" do
14
+ [ ['prefix', '/usr'],
15
+ ['etc', '/etc'],
16
+ ['var', '/var'],
17
+ ['bin', '/usr/bin'],
18
+ ['doc', '/usr/share/doc'],
19
+ ['include', '/usr/include'],
20
+ ['info', '/usr/share/info'],
21
+ ['lib', '/usr/lib'],
22
+ ['libexec', '/usr/libexec'],
23
+ ['man', '/usr/share/man'],
24
+ ['man1', '/usr/share/man/man1'],
25
+ ['man2', '/usr/share/man/man2'],
26
+ ['man3', '/usr/share/man/man3'],
27
+ ['man4', '/usr/share/man/man4'],
28
+ ['man5', '/usr/share/man/man5'],
29
+ ['man6', '/usr/share/man/man6'],
30
+ ['man7', '/usr/share/man/man7'],
31
+ ['man8', '/usr/share/man/man8'],
32
+ ['sbin', '/usr/sbin'],
33
+ ['share', '/usr/share'] ].each do |m|
34
+
35
+ name, path = m
36
+
37
+ describe "##{name}" do
38
+ context "without an argument" do
39
+ it "returns #{path}" do
40
+ helper.send(name).to_s.must_equal path
41
+ end
42
+ end
43
+
44
+ context "with an argument" do
45
+ it "adds the argument to the path" do
46
+ helper.send(name, 'foo/bar').to_s.must_equal "#{path}/foo/bar"
47
+ end
48
+ end
49
+
50
+ context "with a nil argument" do
51
+ it "does not add anything to the path" do
52
+ helper.send(name, nil).to_s.must_equal path
53
+ end
54
+ end
55
+
56
+ context "with installing set to true" do
57
+ before { helper.installing = true}
58
+
59
+ it "adds the destdir as prefix" do
60
+ helper.send(name, 'blah').to_s.must_equal "#{helper.destdir}#{path}/blah"
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "#installing?" do
68
+ context "with installing set to true" do
69
+ before { helper.installing = true}
70
+
71
+ it "returns true" do
72
+ helper.installing?.must_equal true
73
+ end
74
+ end
75
+
76
+ context "with installing set to false" do
77
+ before { helper.installing = false }
78
+
79
+ it "returns true" do
80
+ helper.installing?.must_equal false
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#with_trueprefix" do
86
+ context "with installing set to true" do
87
+ before { helper.installing = true }
88
+
89
+ specify "prefix returns /" do
90
+ helper.with_trueprefix do
91
+ helper.prefix.to_s.must_equal '/usr'
92
+ end
93
+ end
94
+
95
+ it "will restore the previous installing value" do
96
+ helper.with_trueprefix {}
97
+ helper.installing.must_equal true
98
+ end
99
+ end
100
+
101
+ context "with installing set to false" do
102
+ before { helper.installing = false}
103
+
104
+ specify "prefix returns /" do
105
+ helper.with_trueprefix do
106
+ helper.prefix.to_s.must_equal '/usr'
107
+ end
108
+ end
109
+
110
+ it "will restore the previous installing value" do
111
+ helper.with_trueprefix {}
112
+ helper.installing.must_equal false
113
+ end
114
+ end
115
+ end
116
+ end
data/spec/recipe_spec.rb CHANGED
@@ -66,6 +66,8 @@ describe "Recipe" do
66
66
  spec_recipe_attribute(:description, 'A nice program.')
67
67
  spec_recipe_attribute(:homepage, 'http://example.com')
68
68
  spec_recipe_attribute(:maintainer, 'John Doe <john@example.com>')
69
+ spec_recipe_attribute(:sha256, '123456789abcdef')
70
+ spec_recipe_attribute(:sha1, '123456789abcdef')
69
71
  spec_recipe_attribute(:md5, '123456789abcdef')
70
72
  spec_recipe_attribute(:name, 'redis')
71
73
  spec_recipe_attribute(:revision, 12)
@@ -158,6 +160,16 @@ describe "Recipe" do
158
160
  end
159
161
  end
160
162
 
163
+ describe "#local_path" do
164
+ it "returns the path to the local source file" do
165
+ klass.class_eval do
166
+ source 'http://example.com/foo-1.0.tar.gz'
167
+ end
168
+
169
+ File.basename(klass.new(__FILE__).local_path.to_s).must_equal 'foo-1.0.tar.gz'
170
+ end
171
+ end
172
+
161
173
 
162
174
  #############################################################################
163
175
  # Directories
@@ -0,0 +1,176 @@
1
+ require 'spec_helper'
2
+ require 'fpm/cookery/source_integrity_check'
3
+ require 'fpm/cookery/recipe'
4
+
5
+ class TestRecipe < FPM::Cookery::Recipe
6
+ source 'http://example.com/foo.tar.gz'
7
+ end
8
+
9
+ describe "SourceIntegrityCheck" do
10
+ let(:recipe) { TestRecipe.new(__FILE__) }
11
+ let(:check) { FPM::Cookery::SourceIntegrityCheck.new(recipe) }
12
+
13
+ before do
14
+ recipe.source_handler.instance_eval do
15
+ def local_path
16
+ fixture_path('test-source-1.0.tar.gz')
17
+ end
18
+ end
19
+ end
20
+
21
+ describe "without any checksum defined" do
22
+ describe "#error?" do
23
+ it "returns true" do
24
+ check.error?.must_equal true
25
+ end
26
+ end
27
+
28
+ describe "#checksum_missing?" do
29
+ it "returns true" do
30
+ check.checksum_missing?.must_equal true
31
+ end
32
+ end
33
+
34
+ it "has checksum_expected set to nil" do
35
+ check.checksum_expected.must_equal nil
36
+ end
37
+
38
+ it "has checksum_actual set to the sha256 checksum" do
39
+ check.checksum_actual.must_equal '285a6b8098ecc9040ece8f621e37c20edba39545c5d195c4894f410ed9d44b22'
40
+ end
41
+
42
+ it "has filename set" do
43
+ check.filename.must_equal fixture_path('test-source-1.0.tar.gz')
44
+ end
45
+
46
+ it "has digest set to nil" do
47
+ check.digest.must_equal :sha256
48
+ end
49
+ end
50
+
51
+ describe "with a correct sha256 checksum defined" do
52
+ describe "#error?" do
53
+ it "returns false" do
54
+ def recipe.sha256
55
+ '285a6b8098ecc9040ece8f621e37c20edba39545c5d195c4894f410ed9d44b22'
56
+ end
57
+
58
+ check.error?.must_equal false
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "with a wrong sha256 checksum defined" do
64
+ before do
65
+ def recipe.sha256
66
+ 'xxxx6b8098ecc9040ece8f621e37c20edba39545c5d195c4894f410ed9d44b22'
67
+ end
68
+ end
69
+
70
+ describe "#error?" do
71
+ it "returns true" do
72
+ check.error?.must_equal true
73
+ end
74
+ end
75
+
76
+ it "has checksum_expected set to the expected checksum" do
77
+ check.checksum_expected.must_equal 'xxxx6b8098ecc9040ece8f621e37c20edba39545c5d195c4894f410ed9d44b22'
78
+ end
79
+
80
+ it "has checksum_actual set to the actual checksum" do
81
+ check.checksum_actual.must_equal '285a6b8098ecc9040ece8f621e37c20edba39545c5d195c4894f410ed9d44b22'
82
+ end
83
+
84
+ it "has filename set" do
85
+ check.filename.must_equal fixture_path('test-source-1.0.tar.gz')
86
+ end
87
+
88
+ it "has digest set to :sha256" do
89
+ check.digest.must_equal :sha256
90
+ end
91
+ end
92
+
93
+ describe "with a correct sha1 checksum defined" do
94
+ describe "#error?" do
95
+ it "returns false" do
96
+ def recipe.sha1
97
+ 'dd4a8575c60f8122c30d21dfeed9f23f64948bf7'
98
+ end
99
+
100
+ check.error?.must_equal false
101
+ end
102
+ end
103
+ end
104
+
105
+ describe "with a wrong sha1 checksum defined" do
106
+ before do
107
+ def recipe.sha1
108
+ 'xxxx8575c60f8122c30d21dfeed9f23f64948bf7'
109
+ end
110
+ end
111
+
112
+ describe "#error?" do
113
+ it "returns true" do
114
+ check.error?.must_equal true
115
+ end
116
+ end
117
+
118
+ it "has checksum_expected set to the expected checksum" do
119
+ check.checksum_expected.must_equal 'xxxx8575c60f8122c30d21dfeed9f23f64948bf7'
120
+ end
121
+
122
+ it "has checksum_actual set to the actual checksum" do
123
+ check.checksum_actual.must_equal 'dd4a8575c60f8122c30d21dfeed9f23f64948bf7'
124
+ end
125
+
126
+ it "has filename set" do
127
+ check.filename.must_equal fixture_path('test-source-1.0.tar.gz')
128
+ end
129
+
130
+ it "has digest set to :sha1" do
131
+ check.digest.must_equal :sha1
132
+ end
133
+ end
134
+
135
+ describe "with a correct md5 checksum defined" do
136
+ describe "#error?" do
137
+ it "returns false" do
138
+ def recipe.md5
139
+ 'd8f1330c3d1cec72287b88b2a6c1bc91'
140
+ end
141
+
142
+ check.error?.must_equal false
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "with a wrong md5 checksum defined" do
148
+ before do
149
+ def recipe.md5
150
+ 'xxxx330c3d1cec72287b88b2a6c1bc91'
151
+ end
152
+ end
153
+
154
+ describe "#error?" do
155
+ it "returns true" do
156
+ check.error?.must_equal true
157
+ end
158
+ end
159
+
160
+ it "has checksum_expected set to the expected checksum" do
161
+ check.checksum_expected.must_equal 'xxxx330c3d1cec72287b88b2a6c1bc91'
162
+ end
163
+
164
+ it "has checksum_actual set to the actual checksum" do
165
+ check.checksum_actual.must_equal 'd8f1330c3d1cec72287b88b2a6c1bc91'
166
+ end
167
+
168
+ it "has filename set" do
169
+ check.filename.must_equal fixture_path('test-source-1.0.tar.gz')
170
+ end
171
+
172
+ it "has digest set to :md5" do
173
+ check.digest.must_equal :md5
174
+ end
175
+ end
176
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,11 @@
1
1
  require 'minitest/autorun'
2
2
  require 'minitest/pride'
3
+
4
+ def fixture_path(file)
5
+ File.expand_path("../fixtures/#{file}", __FILE__)
6
+ end
7
+
8
+ # For my rspec poisoned brain. ;)
9
+ module Kernel
10
+ alias_method :context, :describe
11
+ end
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.0.1
4
+ version: 0.1.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-11 00:00:00.000000000 Z
12
+ date: 2011-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fpm
16
- requirement: &78016810 !ruby/object:Gem::Requirement
16
+ requirement: &82604870 !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: *78016810
24
+ version_requirements: *82604870
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: minitest
27
- requirement: &78016600 !ruby/object:Gem::Requirement
27
+ requirement: &82604340 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,21 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *78016600
35
+ version_requirements: *82604340
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &82603770 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *82603770
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: fpm
38
- requirement: &78016360 !ruby/object:Gem::Requirement
49
+ requirement: &82603240 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ! '>='
@@ -43,7 +54,7 @@ dependencies:
43
54
  version: '0'
44
55
  type: :runtime
45
56
  prerelease: false
46
- version_requirements: *78016360
57
+ version_requirements: *82603240
47
58
  description: A tool for building software packages with fpm.
48
59
  email:
49
60
  - bernd@tuneafish.de
@@ -52,6 +63,7 @@ executables:
52
63
  extensions: []
53
64
  extra_rdoc_files: []
54
65
  files:
66
+ - .autotest
55
67
  - .gitignore
56
68
  - CHANGELOG.md
57
69
  - Gemfile
@@ -69,13 +81,17 @@ files:
69
81
  - lib/fpm/cookery/source_handler.rb
70
82
  - lib/fpm/cookery/source_handler/curl.rb
71
83
  - lib/fpm/cookery/source_handler/template.rb
84
+ - lib/fpm/cookery/source_integrity_check.rb
72
85
  - lib/fpm/cookery/utils.rb
73
86
  - lib/fpm/cookery/version.rb
74
87
  - recipes/nodejs/recipe.rb
75
88
  - recipes/redis/recipe.rb
76
89
  - recipes/redis/redis-server.init.d
90
+ - spec/fixtures/test-source-1.0.tar.gz
91
+ - spec/path_helper_spec.rb
77
92
  - spec/path_spec.rb
78
93
  - spec/recipe_spec.rb
94
+ - spec/source_integrity_check_spec.rb
79
95
  - spec/spec_helper.rb
80
96
  homepage: ''
81
97
  licenses: []