fpm-cookery 0.5.0 → 0.6.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,8 @@
1
+ # v0.6.0 (2011-11-19)
2
+ * Add a logging/output system.
3
+ * Improve extracted source detection for the curl and svn source handler.
4
+ * Allow absolute paths for pre/post scripts.
5
+
1
6
  # v0.5.0 (2011-11-05)
2
7
  * Add git source handler.
3
8
 
data/README.md CHANGED
@@ -132,7 +132,6 @@ The following is an example recipe. I have some more in my recipe collection
132
132
  * No recipe validation yet.
133
133
  * No dependency validation yet.
134
134
  * No support for patches yet.
135
- * No real logging output yet.
136
135
  * Pretty new and not well tested.
137
136
 
138
137
  ## Credits
@@ -1,11 +1,20 @@
1
1
  require 'fpm/cookery/book_hook'
2
2
  require 'fpm/cookery/recipe'
3
+ require 'fpm/cookery/facts'
3
4
  require 'fpm/cookery/packager'
5
+ require 'fpm/cookery/log'
6
+ require 'fpm/cookery/log/output/console'
7
+ require 'fpm/cookery/log/output/console_color'
4
8
  require 'optparse'
5
9
 
6
10
  module FPM
7
11
  module Cookery
8
12
  class CLI
13
+ def initialize
14
+ @colors = true
15
+ @debug = false
16
+ end
17
+
9
18
  def args(argv)
10
19
  program = File.basename($0)
11
20
  options = OptionParser.new
@@ -16,6 +25,15 @@ module FPM
16
25
  options.separator " clean - cleans up"
17
26
  options.separator "Options:"
18
27
 
28
+ options.on("-c", "--color",
29
+ "Toggle color. (default #{@colors.inspect})") do |o|
30
+ @colors = !@colors
31
+ end
32
+
33
+ options.on("-D", "--debug", "Enable debug output.") do |o|
34
+ @debug = true
35
+ end
36
+
19
37
  options.on("-t TARGET", "--target TARGET",
20
38
  "Set the desired fpm output target (deb, rpm, etc)") do |o|
21
39
  @target = o
@@ -29,6 +47,14 @@ module FPM
29
47
  # Parse flags and such, remainder is all non-option args.
30
48
  remainder = options.parse(argv)
31
49
 
50
+ # Initialize logging.
51
+ FPM::Cookery::Log.enable_debug(@debug)
52
+ if @colors
53
+ FPM::Cookery::Log.output(FPM::Cookery::Log::Output::ConsoleColor.new)
54
+ else
55
+ FPM::Cookery::Log.output(FPM::Cookery::Log::Output::Console.new)
56
+ end
57
+
32
58
  # Default recipe to find is in current directory named 'recipe.rb'
33
59
  @filename = File.expand_path('recipe.rb')
34
60
 
@@ -56,14 +82,13 @@ module FPM
56
82
 
57
83
  def validate
58
84
  unless File.exists?(@filename)
59
- STDERR.puts 'No recipe.rb found in the current directory, abort.'
85
+ Log.error 'No recipe.rb found in the current directory, abort.'
60
86
  exit 1
61
87
  end
62
88
 
63
89
  # Default action is "package"
64
90
  if @actions.empty?
65
91
  @actions = ["package"]
66
- puts "No actions given, assuming 'package'"
67
92
  end
68
93
 
69
94
  # Override the detected platform.
@@ -76,12 +101,10 @@ module FPM
76
101
  end
77
102
 
78
103
  if FPM::Cookery::Facts.target.nil?
79
- STDERR.puts "No target given and we're unable to detect your platform"
104
+ Log.error "No target given and we're unable to detect your platform"
80
105
  exit 1
81
106
  end
82
107
 
83
- puts "Platform: #{FPM::Cookery::Facts.platform}"
84
- puts "Target: #{FPM::Cookery::Facts.target}"
85
108
  end
86
109
 
87
110
  def run
@@ -99,7 +122,7 @@ module FPM
99
122
  when "package" ; packager.dispense
100
123
  else
101
124
  # TODO(sissel): fail if this happens
102
- puts "Unknown action: #{action}"
125
+ Log.error "Unknown action: #{action}"
103
126
  end
104
127
  end
105
128
  end
@@ -0,0 +1,53 @@
1
+ module FPM
2
+ module Cookery
3
+ module Log
4
+ class Color
5
+ CODES = {
6
+ :black => 30,
7
+ :blue => 34,
8
+ :cyan => 36,
9
+ :green => 32,
10
+ :magenta => 35,
11
+ :red => 31,
12
+ :reset => 0,
13
+ :white => 39,
14
+ :yellow => 33,
15
+ }
16
+
17
+ class << self
18
+ def color(name, type = nil)
19
+ tint = CODES[name] || 0
20
+
21
+ case type
22
+ when :bold
23
+ escape("1;#{tint}")
24
+ when :underline
25
+ escape("4;#{tint}")
26
+ else
27
+ escape(tint)
28
+ end
29
+ end
30
+
31
+ def colorize(string, tint, type = nil)
32
+ "#{color(tint, type)}#{string}#{color(:reset)}"
33
+ end
34
+
35
+ def black(string, type = nil) colorize(string, :black, type) end
36
+ def blue(string, type = nil) colorize(string, :blue, type) end
37
+ def cyan(string, type = nil) colorize(string, :cyan, type) end
38
+ def green(string, type = nil) colorize(string, :green, type) end
39
+ def magenta(string, type = nil) colorize(string, :magenta, type) end
40
+ def red(string, type = nil) colorize(string, :red, type) end
41
+ def reset(string, type = nil) colorize(string, :reset, type) end
42
+ def white(string, type = nil) colorize(string, :white, type) end
43
+ def yellow(string, type = nil) colorize(string, :yellow, type) end
44
+
45
+ private
46
+ def escape(num)
47
+ "\033[#{num}m" if $stdout.tty?
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,34 @@
1
+
2
+ module FPM
3
+ module Cookery
4
+ module Log
5
+ module Output
6
+ class Console
7
+ def debug(message)
8
+ STDOUT.puts "DEBUG: #{message}"
9
+ end
10
+
11
+ def info(message)
12
+ STDOUT.puts "===> #{message}"
13
+ end
14
+
15
+ def puts(message)
16
+ STDOUT.puts "#{message}"
17
+ end
18
+
19
+ def warn(message)
20
+ STDERR.puts "WARNING: #{message}"
21
+ end
22
+
23
+ def error(message)
24
+ STDERR.puts "ERROR: #{message}"
25
+ end
26
+
27
+ def fatal(message)
28
+ STDERR.puts "FATAL: #{message}"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ require 'fpm/cookery/log/color'
2
+
3
+ module FPM
4
+ module Cookery
5
+ module Log
6
+ module Output
7
+ class ConsoleColor
8
+ def debug(message)
9
+ puts "#{Color.cyan('DEBUG:')} #{message}"
10
+ end
11
+
12
+ def info(message)
13
+ puts "#{Color.blue('===>')} #{message}"
14
+ end
15
+
16
+ def puts(message)
17
+ Kernel.puts "#{message}"
18
+ end
19
+
20
+ def warn(message)
21
+ STDERR.puts "#{Color.yellow('WARNING:')} #{message}"
22
+ end
23
+
24
+ def error(message)
25
+ STDERR.puts "#{Color.red('ERROR:')} #{message}"
26
+ end
27
+
28
+ def fatal(message)
29
+ STDERR.puts "#{Color.red('FATAL:', :bold)} #{message}"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ module FPM
2
+ module Cookery
3
+ module Log
4
+ module Output
5
+ class Null
6
+ def method_missing(*args)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,44 @@
1
+ require 'fpm/cookery/log/output/null'
2
+
3
+ module FPM
4
+ module Cookery
5
+ module Log
6
+ @debug = false
7
+ @output = FPM::Cookery::Log::Output::Null.new
8
+
9
+ class << self
10
+ def enable_debug(value = true)
11
+ @debug = value
12
+ end
13
+
14
+ def output(out)
15
+ @output = out
16
+ end
17
+
18
+ def debug(message)
19
+ @output.debug(message) if @debug
20
+ end
21
+
22
+ def info(message)
23
+ @output.info(message)
24
+ end
25
+
26
+ def warn(message)
27
+ @output.warn(message)
28
+ end
29
+
30
+ def error(message)
31
+ @output.error(message)
32
+ end
33
+
34
+ def fatal(message)
35
+ @output.fatal(message)
36
+ end
37
+
38
+ def puts(message)
39
+ @output.puts(message)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -3,6 +3,8 @@
3
3
  #require 'fpm/cookery/dependency_inspector'
4
4
  require 'fpm/cookery/utils'
5
5
  require 'fpm/cookery/source_integrity_check'
6
+ require 'fpm/cookery/path'
7
+ require 'fpm/cookery/log'
6
8
 
7
9
  module FPM
8
10
  module Cookery
@@ -22,6 +24,7 @@ module FPM
22
24
  end
23
25
 
24
26
  def cleanup
27
+ Log.info "Cleanup!"
25
28
  # TODO(sissel): do some sanity checking to make sure we don't
26
29
  # accidentally rm -rf the wrong thing.
27
30
  FileUtils.rm_rf(recipe.builddir)
@@ -30,6 +33,12 @@ module FPM
30
33
 
31
34
  def dispense
32
35
  env = ENV.to_hash
36
+ package_name = "#{recipe.name}-#{recipe.version}"
37
+ platform = FPM::Cookery::Facts.platform
38
+ target = FPM::Cookery::Facts.target
39
+
40
+ Log.info "Starting package creation for #{package_name} (#{platform}, #{target})"
41
+ Log.info ''
33
42
 
34
43
  # RecipeInspector.verify!(recipe)
35
44
  # DependencyInspector.verify!(recipe.depends, recipe.build_depends)
@@ -40,26 +49,27 @@ module FPM
40
49
 
41
50
  recipe.cachedir.mkdir
42
51
  Dir.chdir(recipe.cachedir) do
52
+ Log.info "Fetching source: #{source.source_url}"
43
53
  source.fetch
44
54
 
45
55
  if source.checksum?
46
56
  SourceIntegrityCheck.new(recipe).tap do |check|
47
57
  if check.checksum_missing?
48
- STDERR.puts <<-__WARN
49
- WARNING: Recipe does not provide a checksum. (sha256, sha1 or md5)
50
- ------------------------------------------------------------------
58
+ Log.warn 'Recipe does not provide a checksum. (sha256, sha1 or md5)'
59
+ Log.puts <<-__WARN
51
60
  Digest: #{check.digest}
52
61
  Checksum: #{check.checksum_actual}
53
62
  Filename: #{check.filename}
63
+
54
64
  __WARN
55
65
  elsif check.error?
56
- STDERR.puts <<-__ERROR
57
- ERROR: Integrity check failed!
58
- ------------------------------
66
+ Log.error 'Integrity check failed!'
67
+ Log.puts <<-__ERROR
59
68
  Digest: #{check.digest}
60
69
  Checksum expected: #{check.checksum_expected}
61
70
  Checksum actual: #{check.checksum_actual}
62
71
  Filename: #{check.filename}
72
+
63
73
  __ERROR
64
74
  exit 1
65
75
  end
@@ -74,11 +84,12 @@ module FPM
74
84
  Dir.chdir(extracted_source) do
75
85
  #Source::Patches.new(recipe.patches).apply!
76
86
 
77
- build_cookie = build_cookie_name("#{recipe.name}-#{recipe.version}")
87
+ build_cookie = build_cookie_name(package_name)
78
88
 
79
89
  if File.exists?(build_cookie)
80
- STDERR.puts 'Skipping build (`fpm-cook clean` to rebuild)'
90
+ Log.info 'Skipping build (`fpm-cook clean` to rebuild)'
81
91
  else
92
+ Log.info "Building in #{File.expand_path(extracted_source)}"
82
93
  recipe.build and FileUtils.touch(build_cookie)
83
94
  end
84
95
 
@@ -87,6 +98,7 @@ module FPM
87
98
 
88
99
  begin
89
100
  recipe.installing = true
101
+ Log.info "Installing into #{recipe.destdir}"
90
102
  recipe.install
91
103
  ensure
92
104
  recipe.installing = false
@@ -160,11 +172,17 @@ module FPM
160
172
  script_map = {"pre_install" => "--pre-install", "post_install" => "--post-install", "pre_uninstall" => "--pre-uninstall", "post_uninstall" => "--post-uninstall"}
161
173
  %w[pre_install post_install pre_uninstall post_uninstall].each do |script|
162
174
  unless recipe.send(script).nil?
163
- script_file = File.expand_path("../#{recipe.send(script)}", recipe.filename)
175
+ script_file = FPM::Cookery::Path.new(recipe.send(script))
176
+
177
+ # If the script file is an absolute path, just use that path.
178
+ # Otherwise consider the location relative to the recipe.
179
+ unless script_file.absolute?
180
+ script_file = File.expand_path("../#{script_file.to_s}", recipe.filename)
181
+ end
164
182
 
165
183
  if File.exists?(script_file)
166
184
  p_opt = script_map[script]
167
- opts += ["#{p_opt}", script_file]
185
+ opts += ["#{p_opt}", script_file.to_s]
168
186
  else
169
187
  raise "#{script} script '#{script_file}' is missing"
170
188
  end
@@ -181,7 +199,8 @@ module FPM
181
199
 
182
200
  opts << '.'
183
201
 
184
- STDERR.puts ['fpm', opts].flatten.inspect
202
+ Log.info 'Calling fpm to build the package'
203
+ Log.debug ['fpm', opts].flatten.inspect
185
204
  safesystem(*['fpm', opts].flatten)
186
205
  end
187
206
  end
@@ -1,4 +1,5 @@
1
1
  require 'fpm/cookery/source_handler/template'
2
+ require 'fpm/cookery/log'
2
3
 
3
4
  module FPM
4
5
  module Cookery
@@ -9,7 +10,9 @@ module FPM
9
10
  CHECKSUM = true
10
11
 
11
12
  def fetch
12
- unless local_path.exist?
13
+ if local_path.exist?
14
+ Log.info "Using cached file #{local_path}"
15
+ else
13
16
  Dir.chdir(cachedir) do
14
17
  curl(url, local_path) unless local_path.exist?
15
18
  end
@@ -25,8 +28,8 @@ module FPM
25
28
  when '.zip'
26
29
  safesystem('unzip', '-d', local_path.basename('.zip'), local_path)
27
30
  end
31
+ extracted_source
28
32
  end
29
- extracted_source
30
33
  end
31
34
 
32
35
  private
@@ -43,8 +46,10 @@ module FPM
43
46
  when 1
44
47
  entries.first
45
48
  else
46
- ext = Path.new(url).extname
47
- dir = local_path.basename(ext)
49
+ # Use the directory that was created last.
50
+ dir = entries.sort do |a, b|
51
+ File.stat(a).ctime <=> File.stat(b).ctime
52
+ end.last
48
53
 
49
54
  if File.exist?(dir)
50
55
  dir
@@ -1,4 +1,5 @@
1
1
  require 'fpm/cookery/source_handler/template'
2
+ require 'fpm/cookery/log'
2
3
 
3
4
  module FPM
4
5
  module Cookery
@@ -48,7 +49,7 @@ module FPM
48
49
 
49
50
  private
50
51
  def git(command, *args)
51
- #puts "[DEBUG] git #{command} #{args.join(' ')}"
52
+ #Log.debug "git #{command} #{args.join(' ')}"
52
53
  safesystem('git', command, *args)
53
54
  end
54
55
  end
@@ -19,8 +19,8 @@ module FPM
19
19
  def extract
20
20
  Dir.chdir(builddir) do
21
21
  safesystem('cp', '-Rp', local_path, '.')
22
+ extracted_source
22
23
  end
23
- extracted_source
24
24
  end
25
25
 
26
26
  private
@@ -38,8 +38,10 @@ module FPM
38
38
  when 1
39
39
  entries.first
40
40
  else
41
- ext = Path.new(url).extname
42
- dir = local_path.basename(ext)
41
+ # Use the directory that was created last.
42
+ dir = entries.sort do |a, b|
43
+ File.stat(a).ctime <=> File.stat(b).ctime
44
+ end.last
43
45
 
44
46
  if File.exist?(dir)
45
47
  dir
@@ -2,6 +2,7 @@ require 'forwardable'
2
2
  require 'fpm/cookery/source_handler/curl'
3
3
  require 'fpm/cookery/source_handler/svn'
4
4
  require 'fpm/cookery/source_handler/git'
5
+ require 'fpm/cookery/log'
5
6
 
6
7
  module FPM
7
8
  module Cookery
@@ -11,6 +12,8 @@ module FPM
11
12
  extend Forwardable
12
13
  def_delegators :@handler, :fetch, :extract, :local_path, :checksum?
13
14
 
15
+ attr_reader :source_url
16
+
14
17
  def initialize(source_url, options, cachedir, builddir)
15
18
  # The reason for these checks is related to the test cases
16
19
  # Test cases for individual recipe attributes
@@ -38,7 +41,7 @@ module FPM
38
41
  begin
39
42
  self.class.const_get(provider.to_s.capitalize)
40
43
  rescue NameError
41
- STDERR.puts "Specified provider #{provider} does not exist."
44
+ Log.error "Specified provider #{provider} does not exist."
42
45
  exit(1)
43
46
  end
44
47
  end
@@ -1,5 +1,5 @@
1
1
  module FPM
2
2
  module Cookery
3
- VERSION = '0.5.0'
3
+ VERSION = '0.6.0'
4
4
  end
5
5
  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.5.0
4
+ version: 0.6.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-11-05 00:00:00.000000000 Z
12
+ date: 2011-11-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fpm
16
- requirement: &80020110 !ruby/object:Gem::Requirement
16
+ requirement: &82971890 !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: *80020110
24
+ version_requirements: *82971890
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: minitest
27
- requirement: &80019860 !ruby/object:Gem::Requirement
27
+ requirement: &82971550 !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: *80019860
35
+ version_requirements: *82971550
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rake
38
- requirement: &80019630 !ruby/object:Gem::Requirement
38
+ requirement: &82970380 !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: *80019630
46
+ version_requirements: *82970380
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: fpm
49
- requirement: &80019400 !ruby/object:Gem::Requirement
49
+ requirement: &82969850 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *80019400
57
+ version_requirements: *82969850
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: facter
60
- requirement: &80019160 !ruby/object:Gem::Requirement
60
+ requirement: &82968920 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *80019160
68
+ version_requirements: *82968920
69
69
  description: A tool for building software packages with fpm.
70
70
  email:
71
71
  - bernd@tuneafish.de
@@ -86,6 +86,11 @@ files:
86
86
  - lib/fpm/cookery/book_hook.rb
87
87
  - lib/fpm/cookery/cli.rb
88
88
  - lib/fpm/cookery/facts.rb
89
+ - lib/fpm/cookery/log.rb
90
+ - lib/fpm/cookery/log/color.rb
91
+ - lib/fpm/cookery/log/output/console.rb
92
+ - lib/fpm/cookery/log/output/console_color.rb
93
+ - lib/fpm/cookery/log/output/null.rb
89
94
  - lib/fpm/cookery/packager.rb
90
95
  - lib/fpm/cookery/path.rb
91
96
  - lib/fpm/cookery/path_helper.rb
@@ -128,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
133
  version: '0'
129
134
  requirements: []
130
135
  rubyforge_project: fpm-cookery
131
- rubygems_version: 1.8.10
136
+ rubygems_version: 1.8.11
132
137
  signing_key:
133
138
  specification_version: 3
134
139
  summary: A tool for building software packages with fpm.