gpm 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/gpm +8 -0
- data/lib/gpm/cli.rb +23 -0
- data/lib/gpm/file_path_and_permissions.rb +19 -0
- data/lib/gpm/packaging_task.rb +25 -0
- data/lib/gpm/source.rb +55 -0
- data/lib/gpm/source/bundler.rb +55 -0
- data/lib/gpm/source/gem.rb +143 -0
- data/lib/gpm/target.rb +88 -0
- data/lib/gpm/target/deb.rb +131 -0
- data/lib/gpm/target/generate_from_templates.rb +56 -0
- data/lib/gpm/target/step_plugin.rb +22 -0
- data/lib/gpm/target/zip_directories.rb +9 -0
- data/templates/deb/control.tar.gz.dir/control.erb +28 -0
- data/templates/deb/control.tar.gz.dir/md5sums.erb +0 -0
- data/templates/deb/data.tar.gz.dir/usr/share/doc/__name__/changelog.gz.erb +1 -0
- data/templates/deb/data.tar.gz.dir/usr/share/doc/__name__/copyright.erb +1 -0
- data/templates/deb/debian-binary.erb +1 -0
- metadata +175 -0
data/bin/gpm
ADDED
data/lib/gpm/cli.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require_relative 'packaging_task'
|
3
|
+
class GpmCli < Thor
|
4
|
+
|
5
|
+
# gpm package -s <source type> -t <target type> [options]
|
6
|
+
desc "package APP_DIRECTORY_OR_FILE", "package the given app"
|
7
|
+
method_option :source, :type => :string, :aliases => "-s"
|
8
|
+
method_option :target, :type => :string, :aliases => "-t"
|
9
|
+
method_option :workdir, :type => :string, :aliases => "-wd"
|
10
|
+
method_option :destination, :type => :string, :aliases => "-d"
|
11
|
+
|
12
|
+
def package(file_or_directory)
|
13
|
+
raise "Only gem or bundler source at the moment" unless ["gem","bundler"].include? options.source
|
14
|
+
raise "Only deb target at the moment" unless options.target == "deb"
|
15
|
+
package_options = {}
|
16
|
+
{:workdir => :work_dir , :destination => :destination}.each do |in_field, out_field|
|
17
|
+
package_options[out_field] = options[in_field] if options[in_field]
|
18
|
+
end
|
19
|
+
|
20
|
+
PackagingTask.create(file_or_directory, options.source, options.target, package_options).run
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class FilePathAndPermissions < Delegator
|
2
|
+
attr_reader :permissions
|
3
|
+
def initialize(path, permissions = "0444")
|
4
|
+
@path = path
|
5
|
+
@permissions = permissions
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
@path
|
10
|
+
end
|
11
|
+
|
12
|
+
def __getobj__
|
13
|
+
@path
|
14
|
+
end
|
15
|
+
|
16
|
+
def __setobj__(path)
|
17
|
+
@path = path
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class PackagingTask
|
2
|
+
def self.create(file_or_directory, source_name, target_name, options = {})
|
3
|
+
options[:work_dir] ||= Dir.mktmpdir
|
4
|
+
require_relative "source"
|
5
|
+
require_relative "source/#{source_name}"
|
6
|
+
source_class = Kernel.const_get("Source").const_get(source_name.capitalize)
|
7
|
+
source = source_class.create(file_or_directory)
|
8
|
+
|
9
|
+
require_relative "target"
|
10
|
+
require_relative "target/#{target_name}"
|
11
|
+
target_class = Kernel.const_get("Target").const_get(target_name.capitalize)
|
12
|
+
target = target_class.new(options[:work_dir], options)
|
13
|
+
new(source,target)
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(source,target)
|
17
|
+
@source = source
|
18
|
+
@target = target
|
19
|
+
end
|
20
|
+
|
21
|
+
def run
|
22
|
+
@target.create_package(@source)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
data/lib/gpm/source.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module Source
|
2
|
+
class Base
|
3
|
+
DEFAULTS = {
|
4
|
+
# Default version is 1.0 in case nobody told us a specific version.
|
5
|
+
:version => "1.0",
|
6
|
+
:iteration => nil,
|
7
|
+
:epoch => nil,
|
8
|
+
# If architecture is nil, the target package should provide a default.
|
9
|
+
# Special 'architecture' values include "all" (aka rpm's noarch, debian's all)
|
10
|
+
# Another special includes "native" which will be the current platform's arch.
|
11
|
+
:architecture => nil,
|
12
|
+
:dependencies => [],
|
13
|
+
:provides => [],
|
14
|
+
:replaces => [],
|
15
|
+
:conflicts => [],
|
16
|
+
:scripts => [],
|
17
|
+
:config_files => [],
|
18
|
+
:settings => {},
|
19
|
+
:url => "http://nourlgiven.example.com/no/url/given",
|
20
|
+
:category => "default",
|
21
|
+
:license => "unknown",
|
22
|
+
:maintainer => nil,
|
23
|
+
:description => "no description given"
|
24
|
+
}
|
25
|
+
DEFAULTS.each do |field, default_value|
|
26
|
+
define_method field do
|
27
|
+
default_value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
def maintainer
|
31
|
+
# Default maintainer if none given.
|
32
|
+
if @maintainer.nil? or @maintainer.empty?
|
33
|
+
# Reference
|
34
|
+
# http://www.debian.org/doc/manuals/maint-guide/first.en.html
|
35
|
+
# http://wiki.debian.org/DeveloperConfiguration
|
36
|
+
# https://github.com/jordansissel/fpm/issues/37
|
37
|
+
if ENV.include?("DEBEMAIL") and ENV.include?("DEBFULLNAME")
|
38
|
+
# Use DEBEMAIL and DEBFULLNAME as the default maintainer if available.
|
39
|
+
@maintainer = "#{ENV["DEBFULLNAME"]} <#{ENV["DEBEMAIL"]}>"
|
40
|
+
else
|
41
|
+
# TODO(sissel): Maybe support using 'git config' for a default as well?
|
42
|
+
# git config --get user.name, etc can be useful.
|
43
|
+
#
|
44
|
+
# Otherwise default to user@currenthost
|
45
|
+
@maintainer = "<#{ENV["USER"]}@#{Socket.gethostname}>"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
class FilesProvider
|
51
|
+
def files
|
52
|
+
file_contents.keys
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative 'gem'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
|
5
|
+
class Source::Bundler < Source::Gem
|
6
|
+
|
7
|
+
class FilesFromBundlerDirectoryProvider < Source::Gem::FilesFromGemDirectoryProvider
|
8
|
+
|
9
|
+
attr_reader :gemfile,:gemspec
|
10
|
+
def initialize(gemfile,gemspec)
|
11
|
+
super(File.dirname(gemfile),Source::Gem.read_metadata(gemspec).files)
|
12
|
+
@gemfile = gemfile
|
13
|
+
@gemspec = gemspec
|
14
|
+
end
|
15
|
+
def file_contents
|
16
|
+
backup_fields = ["PATH","GEM_PATH"]
|
17
|
+
bundled_files = []
|
18
|
+
directory = File.dirname(@gemfile)
|
19
|
+
old_env = ENV.to_hash
|
20
|
+
Dir.chdir(directory) do
|
21
|
+
Bundler.with_clean_env do
|
22
|
+
old_env.each {|k,_| ENV.delete k}
|
23
|
+
ENV["BUNDLE_GEMFILE"] = @gemfile
|
24
|
+
ENV["PWD"] = directory
|
25
|
+
backup_fields.each {|f| ENV[f] = old_env[f]}
|
26
|
+
FileUtils.rm_rf('.bundle')
|
27
|
+
["bundle install","bundle install --deployment --verbose"].each do |c| # --standalone
|
28
|
+
puts c,`#{c}`
|
29
|
+
end
|
30
|
+
end
|
31
|
+
bundled_files = Dir["vendor/bundle/**/*"]
|
32
|
+
end
|
33
|
+
old_env.each {|k,v| ENV[k] = v}
|
34
|
+
super_contents = super.merge(read_file_contents(bundled_files+[File.basename(gemfile),File.basename(gemspec),'Gemfile.lock'], directory))
|
35
|
+
super_contents
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.create(gemfile)
|
40
|
+
gemspec = Dir[File.join(File.dirname(gemfile),'*.gemspec')].first
|
41
|
+
metadata = read_metadata(gemspec)
|
42
|
+
|
43
|
+
new(metadata,FilesFromBundlerDirectoryProvider.new(File.expand_path(gemfile), gemspec))
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize(*args)
|
47
|
+
super
|
48
|
+
end
|
49
|
+
def architecture
|
50
|
+
"native"
|
51
|
+
end
|
52
|
+
def dependencies
|
53
|
+
["libc6"]
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require_relative '../source'
|
2
|
+
require "rubygems/package"
|
3
|
+
require "rubygems"
|
4
|
+
require 'zlib'
|
5
|
+
|
6
|
+
class Source::Gem < Source::Base
|
7
|
+
class FilesFromGemProvider < Source::FilesProvider
|
8
|
+
def initialize(contents)
|
9
|
+
@gem_file_contents = contents
|
10
|
+
end
|
11
|
+
def file_contents
|
12
|
+
return {} unless @gem_file_contents
|
13
|
+
tar_files = tar_files(StringIO.new(@gem_file_contents))
|
14
|
+
reader = Zlib::GzipReader.new(StringIO.new(tar_files["data.tar.gz"]))
|
15
|
+
contents = tar_files(reader)
|
16
|
+
reader.close
|
17
|
+
contents
|
18
|
+
end
|
19
|
+
def tar_files(io)
|
20
|
+
tar_reader = Gem::Package::TarReader.new(io)
|
21
|
+
tar_files = {}
|
22
|
+
tar_reader.each do |entry|
|
23
|
+
tar_files[entry.full_name] = entry.read
|
24
|
+
end
|
25
|
+
tar_reader.close
|
26
|
+
tar_files
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class FilesFromGemDirectoryProvider < Source::FilesProvider
|
31
|
+
attr_reader :directory
|
32
|
+
def initialize(directory,files)
|
33
|
+
@directory = directory
|
34
|
+
@files = files
|
35
|
+
end
|
36
|
+
def file_contents
|
37
|
+
read_file_contents @files, @directory
|
38
|
+
end
|
39
|
+
def read_file_contents(files,base_directory)
|
40
|
+
file_contents = {}
|
41
|
+
files.each do |f|
|
42
|
+
path = File.join(base_directory,f)
|
43
|
+
file_contents[f] = File.read(path) if File.file?(path)
|
44
|
+
end
|
45
|
+
file_contents
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.read_metadata(gem_file)
|
50
|
+
metadata = nil
|
51
|
+
|
52
|
+
Dir.chdir(File.dirname(gem_file)) do
|
53
|
+
if gem_file.end_with?('.gem')
|
54
|
+
contents = nil
|
55
|
+
File.open(gem_file, 'r') do |f|
|
56
|
+
::Gem::Package.open(f, 'r') do |gem|
|
57
|
+
metadata = gem.metadata
|
58
|
+
end
|
59
|
+
end
|
60
|
+
elsif gem_file.end_with?('.gemspec')
|
61
|
+
metadata = Gem::Specification.load(gem_file)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
metadata
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.create(gem_file)
|
68
|
+
metadata = self.read_metadata(gem_file)
|
69
|
+
|
70
|
+
files_provider = nil
|
71
|
+
Dir.chdir(File.dirname(gem_file)) do
|
72
|
+
if gem_file.end_with?('.gem')
|
73
|
+
File.open(gem_file, 'r') do |f|
|
74
|
+
files_provider = FilesFromGemProvider.new(f.read)
|
75
|
+
end
|
76
|
+
elsif gem_file.end_with?('.gemspec')
|
77
|
+
files_provider = FilesFromGemDirectoryProvider.new(File.expand_path(File.dirname(gem_file)), metadata.files+[File.basename(gem_file)])
|
78
|
+
end
|
79
|
+
end
|
80
|
+
new(metadata, files_provider)
|
81
|
+
end
|
82
|
+
|
83
|
+
attr_reader :metadata, :files_provider
|
84
|
+
def initialize(metadata, files_provider = nil)
|
85
|
+
@metadata = metadata
|
86
|
+
@files_provider = files_provider
|
87
|
+
end
|
88
|
+
|
89
|
+
%w(description license summary version email).each do |method|
|
90
|
+
define_method method do
|
91
|
+
metadata.send(method)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
{:maintainer => :author, :url => :homepage}.each do |out_field, in_field|
|
95
|
+
define_method out_field do
|
96
|
+
metadata.send(in_field)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def name(name_provider=nil)
|
101
|
+
name_provider ||= metadata
|
102
|
+
"rubygem-#{name_provider.name}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def category
|
106
|
+
# TODO: this will be different for different
|
107
|
+
# package managers. Need to decide how to handle this.
|
108
|
+
'Languages/Development/Ruby'
|
109
|
+
end
|
110
|
+
|
111
|
+
def architecture
|
112
|
+
# if the gemspec has extensions defined, then this should be a 'native' arch.
|
113
|
+
if !metadata.extensions.empty?
|
114
|
+
"native"
|
115
|
+
else
|
116
|
+
"all"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def dependencies
|
121
|
+
dependencies = []
|
122
|
+
metadata.runtime_dependencies.map do |dep|
|
123
|
+
# rubygems 1.3.5 doesn't have 'Gem::Dependency#requirement'
|
124
|
+
if dep.respond_to?(:requirement)
|
125
|
+
reqs = dep.requirement.to_s.gsub(/,/, '')
|
126
|
+
else
|
127
|
+
reqs = dep.version_requirements
|
128
|
+
end
|
129
|
+
|
130
|
+
# Some reqs can be ">= a, < b" versions, let's handle that.
|
131
|
+
reqs.to_s.split(/, */).each do |req|
|
132
|
+
dependencies << "#{name(dep)} #{req}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
dependencies
|
136
|
+
end
|
137
|
+
def file_contents
|
138
|
+
@files_provider.nil? ? {} : @files_provider.file_contents
|
139
|
+
end
|
140
|
+
def files
|
141
|
+
@files_provider.files
|
142
|
+
end
|
143
|
+
end
|
data/lib/gpm/target.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'logger'
|
4
|
+
require 'active_support/core_ext/array'
|
5
|
+
require 'active_support/core_ext/class'
|
6
|
+
require_relative 'file_path_and_permissions'
|
7
|
+
|
8
|
+
require_relative 'target/generate_from_templates'
|
9
|
+
require_relative 'target/zip_directories'
|
10
|
+
module Target
|
11
|
+
class Base
|
12
|
+
PHASES = [:file_creation, :packaging]
|
13
|
+
def self.phase_steps_names
|
14
|
+
PHASES.collect {|p| field_name_for_steps p }
|
15
|
+
end
|
16
|
+
def self.field_name_for_steps(phase)
|
17
|
+
"#{phase}_steps".to_sym
|
18
|
+
end
|
19
|
+
def self.steps_for_phase(phase)
|
20
|
+
self.send(field_name_for_steps(phase))
|
21
|
+
end
|
22
|
+
class_inheritable_array *phase_steps_names
|
23
|
+
phase_steps_names.each {|p| self.send("#{p}=".to_sym,[])}
|
24
|
+
|
25
|
+
include GenerateFromTemplates
|
26
|
+
include ZipDirectories
|
27
|
+
attr_reader :work_dir, :options
|
28
|
+
def initialize(work_dir, options = {})
|
29
|
+
@work_dir = work_dir
|
30
|
+
@logger = ::Logger.new(STDERR)
|
31
|
+
@options = options
|
32
|
+
end
|
33
|
+
|
34
|
+
def type
|
35
|
+
self.class.name.downcase.gsub("target::","")
|
36
|
+
end
|
37
|
+
|
38
|
+
def package_dir
|
39
|
+
File.join(work_dir,'package_files')
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_package(source)
|
43
|
+
@origin_dir = Dir.getwd
|
44
|
+
FileUtils.mkdir_p package_dir
|
45
|
+
::Dir.chdir(package_dir) do
|
46
|
+
self.class.phase_steps_names.each do |steps|
|
47
|
+
self.class.send(steps).each do |step|
|
48
|
+
instance_exec *([source][0,step.parameters.size]), &step
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def write_file_contents(file_contents)
|
55
|
+
file_contents.each do |file_name, content|
|
56
|
+
FileUtils.mkdir_p(File.dirname(file_name))
|
57
|
+
File.open(file_name,"w") do |file|
|
58
|
+
file.print content
|
59
|
+
end
|
60
|
+
File.chmod(file_name.permissions, file_name.to_s) if file_name.is_a? FilePathAndPermissions
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def write_file_contents_in_directory(file_contents,directory)
|
65
|
+
FileUtils.mkdir_p directory
|
66
|
+
Dir.chdir(directory) do
|
67
|
+
write_file_contents(file_contents)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def tar_directory(directory, options = {})
|
72
|
+
FileUtils.mkdir_p(directory)
|
73
|
+
::Dir.chdir(directory) do
|
74
|
+
tar(File.join('..',directory.gsub('.dir','')),[''], options)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def tar(output, files, options={})
|
79
|
+
exec("tar -zcf #{output} #{files.map{ |f| "./#{f}" }.join(" ")} "+options.collect {|k,v| "--#{k}=#{v}"}.join(" "))
|
80
|
+
end
|
81
|
+
|
82
|
+
def exec(*args)
|
83
|
+
puts args.join(" ")
|
84
|
+
success = system(*args)
|
85
|
+
puts "#{args.join(" ")} did not complete successfully!" unless success
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require_relative '../target'
|
2
|
+
require 'erb'
|
3
|
+
require 'delegate'
|
4
|
+
require_relative 'step_plugin'
|
5
|
+
|
6
|
+
class Target::Deb < Target::Base
|
7
|
+
include StepPlugin
|
8
|
+
class DebianSourceWrapper < Delegator
|
9
|
+
def initialize(source)
|
10
|
+
super
|
11
|
+
@delegate_sd_obj = source || raise("nil source")
|
12
|
+
@logger = ::Logger.new(STDERR)
|
13
|
+
end
|
14
|
+
|
15
|
+
def __getobj__
|
16
|
+
@delegate_sd_obj # return object we are delegating to, required
|
17
|
+
end
|
18
|
+
|
19
|
+
def __setobj__(source)
|
20
|
+
@delegate_sd_obj = source # change delegation object, a feature we're providing
|
21
|
+
end
|
22
|
+
|
23
|
+
def name
|
24
|
+
clean_package_name(__getobj__.name)
|
25
|
+
end
|
26
|
+
def clean_package_name(name)
|
27
|
+
if name =~ /[A-Z]/
|
28
|
+
@logger.warn("Debian tools (dpkg/apt) don't do well with packages " \
|
29
|
+
"that use capital letters in the name. In some cases it will " \
|
30
|
+
"automatically downcase them, in others it will not. It is confusing." \
|
31
|
+
"Best to not use any capital letters at all.")
|
32
|
+
name = name.downcase
|
33
|
+
end
|
34
|
+
|
35
|
+
if name.include?("_")
|
36
|
+
@logger.info("Package name '#{name}' includes underscores, converting" \
|
37
|
+
" to dashes")
|
38
|
+
name = name.gsub(/[_]/, "-")
|
39
|
+
end
|
40
|
+
|
41
|
+
return name
|
42
|
+
end
|
43
|
+
def architecture
|
44
|
+
architecture = __getobj__.architecture
|
45
|
+
if architecture.nil? or architecture == "native"
|
46
|
+
# Default architecture should be 'native' which we'll need
|
47
|
+
# to ask the system about.
|
48
|
+
arch = %x{dpkg --print-architecture}.chomp
|
49
|
+
if $?.exitstatus != 0
|
50
|
+
arch = %x{uname -m}.chomp
|
51
|
+
@logger.warn("Can't find 'dpkg' tool (need it to get default " \
|
52
|
+
"architecture!). Please specificy --architecture " \
|
53
|
+
"specifically. (Defaulting now to #{arch})")
|
54
|
+
end
|
55
|
+
arch
|
56
|
+
elsif architecture == "x86_64"
|
57
|
+
# Debian calls x86_64 "amd64"
|
58
|
+
"amd64"
|
59
|
+
else
|
60
|
+
architecture
|
61
|
+
end
|
62
|
+
end # def architecture
|
63
|
+
|
64
|
+
def default_output
|
65
|
+
name_and_version = "#{name}_#{version}"
|
66
|
+
architecture_and_type = "#{architecture}.#{type}"
|
67
|
+
if iteration
|
68
|
+
"#{name_and_version}-#{iteration}_#{architecture_and_type}"
|
69
|
+
else
|
70
|
+
"#{name_and_version}_#{architecture_and_type}"
|
71
|
+
end
|
72
|
+
end # def default_output
|
73
|
+
def fix_dependency(dep)
|
74
|
+
if dep =~ /[\(,\|]/
|
75
|
+
# Don't "fix" ones that could appear well formed already.
|
76
|
+
else
|
77
|
+
da = dep.split(/ +/)
|
78
|
+
if da.size > 1
|
79
|
+
# Convert strings 'foo >= bar' to 'foo (>= bar)'
|
80
|
+
dep = "#{da[0]} (#{da[1]} #{da[2]})"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
name_re = /^[^ \(]+/
|
85
|
+
name = dep[name_re]
|
86
|
+
name = clean_package_name(name)
|
87
|
+
|
88
|
+
|
89
|
+
# Convert gem ~> X.Y.Z to '>= X.Y.Z' and << X.Y+1.0
|
90
|
+
if dep =~ /\(~>/
|
91
|
+
name, version = dep.gsub(/[()~>]/, "").split(/ +/)[0..1]
|
92
|
+
nextversion = version.split(".").collect { |v| v.to_i }
|
93
|
+
l = nextversion.length
|
94
|
+
nextversion[l-2] += 1
|
95
|
+
nextversion[l-1] = 0
|
96
|
+
nextversion = nextversion.join(".")
|
97
|
+
return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
|
98
|
+
# ignore iterations for = dependencies if flag specified
|
99
|
+
elsif (m = dep.match(/(\S+)\s+\(= (.+)\)/)) && self.settings[:ignore_iteration]
|
100
|
+
name, version = m[1..2]
|
101
|
+
nextversion = version.split('.').collect { |v| v.to_i }
|
102
|
+
nextversion[-1] += 1
|
103
|
+
nextversion = nextversion.join(".")
|
104
|
+
return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
|
105
|
+
else
|
106
|
+
return dep
|
107
|
+
end
|
108
|
+
end
|
109
|
+
def type
|
110
|
+
"deb"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def all_binaries
|
115
|
+
Dir["**/*.so"]
|
116
|
+
end
|
117
|
+
|
118
|
+
in_phase(:file_creation) { exec("strip --strip-unneeded #{all_binaries.join(' ')}") unless all_binaries.empty? }
|
119
|
+
in_phase(:file_creation) { exec("chrpath --delete #{all_binaries.join(' ')}") unless all_binaries.empty? }
|
120
|
+
in_phase(:packaging) {|source| exec("ar -qc ../#{source.default_output} debian-binary control.tar.gz data.tar.gz") }
|
121
|
+
in_phase(:packaging) {|source| FileUtils.cp("../#{source.default_output}",@origin_dir) }
|
122
|
+
|
123
|
+
def create_package(source)
|
124
|
+
super(DebianSourceWrapper.new(source))
|
125
|
+
end
|
126
|
+
def write_files_to_package_dir(source)
|
127
|
+
super
|
128
|
+
write_file_contents_in_directory source.file_contents, File.join("data.tar.gz.dir",options[:destination] || "")
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative 'step_plugin'
|
2
|
+
require_relative '../file_path_and_permissions'
|
3
|
+
module GenerateFromTemplates
|
4
|
+
include StepPlugin
|
5
|
+
in_phase(:file_creation) { |source| write_files_to_package_dir(source) }
|
6
|
+
|
7
|
+
def template_paths
|
8
|
+
@template_paths ||= Dir["#{template_dir}/**/*.erb"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def template_dir
|
12
|
+
File.expand_path("../../../templates/#{type}/", File.dirname(__FILE__))
|
13
|
+
end
|
14
|
+
|
15
|
+
def template_files
|
16
|
+
template_paths.map {|tp| tp.gsub(/#{template_dir}\//,"")}
|
17
|
+
end
|
18
|
+
|
19
|
+
def templates
|
20
|
+
Hash[*template_paths.map {|file| FilePathAndPermissions.new(file.gsub(/#{template_dir}\//,"").gsub(".erb",""),File.new(file).lstat.mode)}.zip(template_paths.map do |template_file|
|
21
|
+
tpl = File.read(template_file)
|
22
|
+
::ERB.new(tpl, nil, "-")
|
23
|
+
end).flatten]
|
24
|
+
end
|
25
|
+
|
26
|
+
def file_contents_from_templates(source)
|
27
|
+
Hash[*templates.map {|file,template| [packaged_file_name(file,source),file_content(template, source, file)]}.flatten]
|
28
|
+
end
|
29
|
+
|
30
|
+
def write_files_to_package_dir(source)
|
31
|
+
write_file_contents_in_directory file_contents_from_templates(source), '.'
|
32
|
+
end
|
33
|
+
|
34
|
+
REPLACEMENT_REGEXP = /__(\w+)__/
|
35
|
+
def packaged_file_name(file_name,source)
|
36
|
+
to_replace = file_name.scan(REPLACEMENT_REGEXP).flatten
|
37
|
+
to_replace.each do |replace|
|
38
|
+
file_name = file_name.gsub("__#{replace}__",source.send(replace.to_sym))
|
39
|
+
end
|
40
|
+
file_name
|
41
|
+
end
|
42
|
+
|
43
|
+
def file_content(template, source, file)
|
44
|
+
contents = template.result(source.instance_eval{ binding() })
|
45
|
+
basename = File.basename(file)
|
46
|
+
if file.end_with?(".gz")
|
47
|
+
zipped = ""
|
48
|
+
gz = Zlib::GzipWriter.new(StringIO.new(zipped))
|
49
|
+
gz.write contents
|
50
|
+
gz.close
|
51
|
+
contents = zipped
|
52
|
+
end
|
53
|
+
contents
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module StepPlugin
|
2
|
+
def self.included(base)
|
3
|
+
if base.is_a? Class
|
4
|
+
def base.in_phase(phase, &block)
|
5
|
+
self.steps_for_phase(phase) << block
|
6
|
+
end
|
7
|
+
elsif base.is_a? Module
|
8
|
+
def base.in_phase(phase, &block)
|
9
|
+
@phase_blocks||= {}
|
10
|
+
@phase_blocks[phase] ||= []
|
11
|
+
@phase_blocks[phase] << block
|
12
|
+
end
|
13
|
+
def base.included(clazz)
|
14
|
+
@phase_blocks.each do |phase, blocks|
|
15
|
+
blocks.each do |block|
|
16
|
+
clazz.steps_for_phase(phase) << block
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Package: <%= name %>
|
2
|
+
Version: <%= "#{epoch}:" if epoch %><%= version %><%= iteration && '-'+iteration.to_s %>
|
3
|
+
Architecture: <%= architecture %>
|
4
|
+
Maintainer: <%= maintainer or "<unknown>" %><%= " <#{email}>".gsub(" <>","") %>
|
5
|
+
<% if !dependencies.empty? -%>
|
6
|
+
<% properdeps = dependencies.collect { |d| fix_dependency(d) }.flatten -%>
|
7
|
+
Depends: <%= properdeps.flatten.join(", ") %>
|
8
|
+
<% end -%>
|
9
|
+
<% if !conflicts.empty? -%>
|
10
|
+
Conflicts: <%= conflicts.join(", ") %>
|
11
|
+
<% end -%>
|
12
|
+
<% if !provides.empty? -%>
|
13
|
+
Provides: <%= provides.join(", ") %>
|
14
|
+
<% end -%>
|
15
|
+
<% if !replaces.empty? -%>
|
16
|
+
<% properrepl = replaces.collect { |d| fix_dependency(d) }.flatten -%>
|
17
|
+
Replaces: <%= properrepl.flatten.join(", ") %>
|
18
|
+
<% end -%>
|
19
|
+
Standards-Version: 3.9.1
|
20
|
+
Section: <%= category or "unknown" %>
|
21
|
+
Priority: extra
|
22
|
+
Homepage: <%= url or "http://nourlgiven.example.com/" %>
|
23
|
+
<% lines = (description or "no description given").split("\n") -%>
|
24
|
+
<% firstline, *remainder = lines -%>
|
25
|
+
Description: <%= firstline %>
|
26
|
+
<% if remainder.any? -%>
|
27
|
+
<%= remainder.collect { |l| l =~ /^ *$/ ? " ." : " #{l}" }.join("\n") %>
|
28
|
+
<% end -%>
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= name %> (<%= version %>) unstable; urgency=low
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= license %>
|
@@ -0,0 +1 @@
|
|
1
|
+
2.0
|
metadata
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gpm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Martin Mauch
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-08-16 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: &76126640 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *76126640
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: thor
|
27
|
+
requirement: &76124890 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.14.6
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *76124890
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: activesupport
|
38
|
+
requirement: &76124160 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *76124160
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: i18n
|
49
|
+
requirement: &76115690 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *76115690
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: cucumber
|
60
|
+
requirement: &76115270 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.0.2
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *76115270
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: aruba
|
71
|
+
requirement: &76114730 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.4.3
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *76114730
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: guard
|
82
|
+
requirement: &76114270 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.5.1
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *76114270
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: guard-cucumber
|
93
|
+
requirement: &76113790 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 0.5.2
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *76113790
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: guard-bundler
|
104
|
+
requirement: &76113160 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.1.3
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *76113160
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: guard-rspec
|
115
|
+
requirement: &76112590 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ~>
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: 0.4.0
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *76112590
|
124
|
+
description: Convert directories, rpms, python eggs, rubygems, and more to rpms, debs,
|
125
|
+
solaris packages and more. Win at package management without wasting pointless hours
|
126
|
+
debugging bad rpm specs!
|
127
|
+
email: mauch@crealytics.de
|
128
|
+
executables:
|
129
|
+
- gpm
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- lib/gpm/cli.rb
|
134
|
+
- lib/gpm/source/bundler.rb
|
135
|
+
- lib/gpm/source/gem.rb
|
136
|
+
- lib/gpm/packaging_task.rb
|
137
|
+
- lib/gpm/file_path_and_permissions.rb
|
138
|
+
- lib/gpm/target.rb
|
139
|
+
- lib/gpm/source.rb
|
140
|
+
- lib/gpm/target/generate_from_templates.rb
|
141
|
+
- lib/gpm/target/deb.rb
|
142
|
+
- lib/gpm/target/zip_directories.rb
|
143
|
+
- lib/gpm/target/step_plugin.rb
|
144
|
+
- bin/gpm
|
145
|
+
- templates/deb/data.tar.gz.dir/usr/share/doc/__name__/copyright.erb
|
146
|
+
- templates/deb/data.tar.gz.dir/usr/share/doc/__name__/changelog.gz.erb
|
147
|
+
- templates/deb/control.tar.gz.dir/md5sums.erb
|
148
|
+
- templates/deb/control.tar.gz.dir/control.erb
|
149
|
+
- templates/deb/debian-binary.erb
|
150
|
+
homepage: https://github.com/crealytics/gpm
|
151
|
+
licenses: []
|
152
|
+
post_install_message:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
155
|
+
- lib
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
none: false
|
159
|
+
requirements:
|
160
|
+
- - ! '>='
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
none: false
|
165
|
+
requirements:
|
166
|
+
- - ! '>='
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
requirements: []
|
170
|
+
rubyforge_project:
|
171
|
+
rubygems_version: 1.8.7
|
172
|
+
signing_key:
|
173
|
+
specification_version: 3
|
174
|
+
summary: gpm - Grand Package Manager
|
175
|
+
test_files: []
|