fpm-cookery 0.0.1

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.
@@ -0,0 +1,75 @@
1
+ require 'pathname'
2
+ require 'fileutils'
3
+
4
+ module FPM
5
+ module Cookery
6
+ class Path < Pathname
7
+ if '1.9' <= RUBY_VERSION
8
+ alias_method :to_str, :to_s
9
+ end
10
+
11
+ def self.pwd(path = nil)
12
+ new(Dir.pwd)/path
13
+ end
14
+
15
+ def +(other)
16
+ other = Path.new(other) unless Path === other
17
+ Path.new(plus(@path, other.to_s))
18
+ end
19
+
20
+ def /(path)
21
+ self + (path || '').gsub(%r{^/}, '')
22
+ end
23
+
24
+ def mkdir
25
+ FileUtils.mkdir_p(self.to_s)
26
+ end
27
+
28
+ def install(src)
29
+ case src
30
+ when Array
31
+ src.collect {|src| install_p(src) }
32
+ when Hash
33
+ src.collect {|src, new_basename| install_p(src, new_basename) }
34
+ else
35
+ install_p(src)
36
+ end
37
+ end
38
+
39
+ def install_p(src, new_basename = nil)
40
+ if new_basename
41
+ new_basename = File.basename(new_basename) # rationale: see Pathname.+
42
+ dst = self/new_basename
43
+ return_value = Path.new(dst)
44
+ else
45
+ dst = self
46
+ return_value = self/File.basename(src)
47
+ end
48
+
49
+ src = src.to_s
50
+ dst = dst.to_s
51
+
52
+ # if it's a symlink, don't resolve it to a file because if we are moving
53
+ # files one by one, it's likely we will break the symlink by moving what
54
+ # it points to before we move it
55
+ # and also broken symlinks are not the end of the world
56
+ raise "#{src} does not exist" unless File.symlink? src or File.exist? src
57
+
58
+ mkpath
59
+ FileUtils.cp_r src, dst, :preserve => true
60
+
61
+ # if File.symlink? src
62
+ # # we use the BSD mv command because FileUtils copies the target and
63
+ # # not the link! I'm beginning to wish I'd used Python quite honestly!
64
+ # raise unless Kernel.system 'mv', src, dst
65
+ # else
66
+ # # we mv when possible as it is faster and you should only be using
67
+ # # this function when installing from the temporary build directory
68
+ # FileUtils.mv src, dst
69
+ # end
70
+
71
+ return return_value
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,49 @@
1
+ require 'fpm/cookery/path'
2
+
3
+ module FPM
4
+ module Cookery
5
+ module PathHelper
6
+ attr_accessor :installing
7
+
8
+ def installing?
9
+ installing
10
+ end
11
+
12
+ # Most of the path helper stuff comes from brew2deb and homebrew.
13
+ def prefix(path = nil)
14
+ current_pathname_for('usr')/path
15
+ end
16
+
17
+ def etc(path = nil)
18
+ current_pathname_for('etc')/path
19
+ end
20
+
21
+ def var(path = nil)
22
+ current_pathname_for('var')/path
23
+ end
24
+
25
+ def bin(path = nil) prefix/'bin'/path end
26
+ def doc(path = nil) prefix/'share/doc'/path/name end
27
+ def include(path = nil) prefix/'include'/path end
28
+ def info(path = nil) prefix/'share/info'/path end
29
+ def lib(path = nil) prefix/'lib'/path end
30
+ def libexec(path = nil) prefix/'libexec'/path end
31
+ def man(path = nil) prefix/'share/man'/path end
32
+ def man1(path = nil) man/'man1'/path end
33
+ def man2(path = nil) man/'man2'/path end
34
+ def man3(path = nil) man/'man3'/path end
35
+ def man4(path = nil) man/'man4'/path end
36
+ def man5(path = nil) man/'man5'/path end
37
+ def man6(path = nil) man/'man6'/path end
38
+ def man7(path = nil) man/'man7'/path end
39
+ def man8(path = nil) man/'man8'/path end
40
+ def sbin(path = nil) prefix/'sbin'/path end
41
+ def share(path = nil) prefix/'share'/path end
42
+
43
+ private
44
+ def current_pathname_for(dir)
45
+ installing? ? destdir/dir : Path.new("/#{dir}")
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,88 @@
1
+ require 'fileutils'
2
+ require 'fpm/cookery/source_handler'
3
+ require 'fpm/cookery/utils'
4
+ require 'fpm/cookery/path_helper'
5
+
6
+ module FPM
7
+ module Cookery
8
+ class Recipe
9
+ include FileUtils
10
+ include FPM::Cookery::Utils
11
+ include FPM::Cookery::PathHelper
12
+
13
+ def self.attr_rw(*attrs)
14
+ attrs.each do |attr|
15
+ class_eval %Q{
16
+ def self.#{attr}(value = nil)
17
+ value.nil? ? @#{attr} : @#{attr} = value
18
+ end
19
+
20
+ def #{attr}
21
+ self.class.#{attr}
22
+ end
23
+ }
24
+ end
25
+ end
26
+
27
+ def self.attr_rw_list(*attrs)
28
+ attrs.each do |attr|
29
+ class_eval %Q{
30
+ def self.#{attr}(*list)
31
+ @#{attr} ||= superclass.respond_to?(:#{attr}) ? superclass.#{attr} : []
32
+ @#{attr} << list
33
+ @#{attr}.flatten!
34
+ @#{attr}.uniq!
35
+ @#{attr}
36
+ end
37
+
38
+ def #{attr}
39
+ self.class.#{attr}
40
+ end
41
+ }
42
+ end
43
+ end
44
+
45
+ attr_rw :arch, :description, :homepage, :maintainer, :md5, :name,
46
+ :revision, :section, :spec, :vendor, :version
47
+
48
+ attr_rw_list :build_depends, :config_files, :conflicts, :depends,
49
+ :exclude, :patches, :provides, :replaces
50
+
51
+ class << self
52
+ def source(source = nil, spec = {})
53
+ return @source if source.nil?
54
+ @source = source
55
+ @spec = spec
56
+ end
57
+ alias_method :url, :source
58
+ end
59
+
60
+ def source
61
+ self.class.source
62
+ end
63
+
64
+ def initialize(filename)
65
+ @filename = Path.new(filename).expand_path
66
+ @source_handler = SourceHandler.new(source, spec, cachedir, builddir)
67
+
68
+ # Set some defaults.
69
+ vendor || self.class.vendor('fpm')
70
+ revision || self.class.revision(0)
71
+ end
72
+
73
+ attr_reader :filename, :source_handler
74
+
75
+ def workdir=(value) @workdir = Path.new(value) end
76
+ def destdir=(value) @destdir = Path.new(value) end
77
+ def builddir=(value) @builddir = Path.new(value) end
78
+ def pkgdir=(value) @pkgdir = Path.new(value) end
79
+ def cachedir=(value) @cachedir = Path.new(value) end
80
+
81
+ def workdir(path = nil) (@workdir ||= filename.dirname)/path end
82
+ def destdir(path = nil) (@destdir ||= workdir('tmp-dest'))/path end
83
+ def builddir(path = nil) (@builddir ||= workdir('tmp-build'))/path end
84
+ def pkgdir(path = nil) (@pkgdir ||= workdir('pkg'))/path end
85
+ def cachedir(path = nil) (@cachedir ||= workdir('cache'))/path end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,28 @@
1
+ require 'forwardable'
2
+ require 'fpm/cookery/source_handler/curl'
3
+
4
+ module FPM
5
+ module Cookery
6
+ class SourceHandler
7
+ extend Forwardable
8
+ def_delegators :@handler, :fetch, :extract, :local_path
9
+
10
+ def initialize(source_url, options, cachedir, builddir)
11
+ @source_url = source_url
12
+ @options = options
13
+ @cachedir = cachedir
14
+ @builddir = builddir
15
+ @handler = get_source_handler
16
+ end
17
+
18
+ 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)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ require 'fpm/cookery/source_handler/template'
2
+
3
+ module FPM
4
+ module Cookery
5
+ class SourceHandler
6
+ class Curl < FPM::Cookery::SourceHandler::Template
7
+ def fetch
8
+ unless local_path.exist?
9
+ Dir.chdir(cachedir) do
10
+ curl(url, local_path) unless local_path.exist?
11
+ end
12
+ end
13
+ local_path
14
+ end
15
+
16
+ def extract
17
+ Dir.chdir(builddir) do
18
+ case local_path.extname
19
+ when '.bz2', '.gz', '.tgz'
20
+ safesystem('tar', 'xf', local_path)
21
+ end
22
+ end
23
+ extracted_source
24
+ end
25
+
26
+ private
27
+ def curl(url, path)
28
+ safesystem('curl', '-fL', '--progress-bar', '-o', path, url)
29
+ end
30
+
31
+ def extracted_source
32
+ entries = Dir['*'].select {|dir| File.directory?(dir) }
33
+
34
+ case entries.size
35
+ when 0
36
+ raise "Empty archive! (#{local_path})"
37
+ when 1
38
+ entries.first
39
+ else
40
+ ext = Path.new(url).extname
41
+ dir = local_path.basename(ext)
42
+
43
+ if File.exist?(dir)
44
+ dir
45
+ else
46
+ raise "Could not find source directory for #{local_path.basename}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ require 'fpm/cookery/utils'
2
+
3
+ module FPM
4
+ module Cookery
5
+ class SourceHandler
6
+ class Template
7
+ include FPM::Cookery::Utils
8
+
9
+ attr_reader :url, :options, :cachedir, :builddir
10
+
11
+ def initialize(source_url, options, cachedir, builddir)
12
+ @url = source_url
13
+ @options = options
14
+ @cachedir = cachedir
15
+ @builddir = builddir
16
+ end
17
+
18
+ def fetch
19
+ raise "#{self}#fetch not implemented!"
20
+ end
21
+
22
+ def extract
23
+ raise "#{self}#extract not implemented!"
24
+ end
25
+
26
+ def local_path
27
+ @local_path ||= cachedir/(options[:as] || File.basename(url))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,62 @@
1
+ module FPM
2
+ module Cookery
3
+ module Utils
4
+ protected
5
+ # From fpm. (lib/fpm/util.rb)
6
+ def safesystem(*args)
7
+ success = system(*args)
8
+ if !success
9
+ raise "'system(#{args.inspect})' failed with error code: #{$?.exitstatus}"
10
+ end
11
+ return success
12
+ end
13
+
14
+ # From brew2deb. (lib/debian_formula.rb)
15
+ def configure(*args)
16
+ if args.last.is_a?(Hash)
17
+ opts = args.pop
18
+ args += opts.map{ |k,v|
19
+ option = k.to_s.gsub('_','-')
20
+ if v == true
21
+ "--#{option}"
22
+ else
23
+ "--#{option}=#{v}"
24
+ end
25
+ }
26
+ end
27
+
28
+ safesystem './configure', *args
29
+ end
30
+
31
+ # From brew2deb. (lib/debian_formula.rb)
32
+ def make(*args)
33
+ env = args.pop if args.last.is_a?(Hash)
34
+ env ||= {}
35
+
36
+ args += env.map{ |k,v| "#{k}=#{v}" }
37
+ args.map!{ |a| a.to_s }
38
+
39
+ safesystem 'make', *args
40
+ end
41
+
42
+ # From homebrew. (Library/Homebrew/utils.rb)
43
+ def inline_replace(path, before = nil, after = nil)
44
+ [*path].each do |path|
45
+ f = File.open(path, 'r')
46
+ s = f.read
47
+
48
+ if before == nil and after == nil
49
+ # s.extend(StringInreplaceExtension)
50
+ yield s
51
+ else
52
+ s.gsub!(before, after)
53
+ end
54
+
55
+ f.reopen(path, 'w').write(s)
56
+ f.close
57
+ end
58
+ end
59
+ alias_method :inreplace, :inline_replace # homebrew compat
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ module FPM
2
+ module Cookery
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,35 @@
1
+ class NodeJS < FPM::Cookery::Recipe
2
+ source 'http://nodejs.org/dist/node-v0.4.10.tar.gz'
3
+ # head 'https://github.com/joyent/node.git'
4
+ homepage 'http://nodejs.org/'
5
+ md5 '2e8b82a9788308727e285d2d4a129c29'
6
+
7
+ section 'interpreters'
8
+ name 'nodejs'
9
+ version '0.4.10+github1'
10
+ description 'Evented I/O for V8 JavaScript'
11
+
12
+ build_depends \
13
+ 'libssl-dev',
14
+ 'g++',
15
+ 'python'
16
+
17
+ depends \
18
+ 'openssl'
19
+
20
+ def build
21
+ inreplace 'wscript' do |s|
22
+ s.gsub! '/usr/local', '/usr'
23
+ s.gsub! '/opt/local/lib', '/usr/lib'
24
+ end
25
+
26
+ configure \
27
+ :prefix => prefix,
28
+ :debug => true
29
+ make
30
+ end
31
+
32
+ def install
33
+ make :install, 'DESTDIR' => destdir
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ class Redis < FPM::Cookery::Recipe
2
+ homepage 'http://redis.io'
3
+ source 'http://redis.googlecode.com/files/redis-2.2.5.tar.gz'
4
+ md5 'fe6395bbd2cadc45f4f20f6bbe05ed09'
5
+
6
+ name 'redis-server'
7
+ version '2.2.5'
8
+ # revision '0' # => redis-server-2.2.5+fpm1
9
+
10
+ description 'An advanced key-value store.'
11
+
12
+ conflicts 'redis-server'
13
+
14
+ config_files '/etc/redis/redis.conf'
15
+
16
+ patches 'patches/test.patch'
17
+
18
+ def build
19
+ make
20
+
21
+ inline_replace 'redis.conf' do |s|
22
+ s.gsub! 'daemonize no', 'daemonize yes # non-default'
23
+ end
24
+ end
25
+
26
+ def install
27
+ # make :install, 'DESTDIR' => destdir
28
+
29
+ var('lib/redis').mkdir
30
+
31
+ %w(run log/redis).each {|p| var(p).mkdir }
32
+
33
+ bin.install ['src/redis-server', 'src/redis-cli']
34
+
35
+ etc('redis').install 'redis.conf'
36
+ etc('init.d').install workdir('redis-server.init.d') => 'redis-server'
37
+ end
38
+ end