gpm 0.0.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ chmod 0664 'templates/deb/control.tar.gz.dir/control.erb'
2
+ chmod 0755 'templates/deb/control.tar.gz.dir/prerm.erb'
3
+ chmod 0755 'templates/deb/control.tar.gz.dir/postinst.erb'
4
+ chmod 0664 'templates/deb/data.tar.gz.dir/usr/share/doc/__name__/changelog.Debian.gz.erb'
@@ -1,23 +1,31 @@
1
1
  require 'thor'
2
2
  require_relative 'packaging_task'
3
3
  class GpmCli < Thor
4
-
4
+ def self.supported_sources
5
+ ["gem","bundler"]
6
+ end
7
+ def self.supported_targets
8
+ ["deb"]
9
+ end
5
10
  # 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
+ desc "package APP_DIRECTORY_OR_FILE", "Packages the app given in a specified source format to a desired target format"
12
+ method_option :source, :type => :string, :aliases => "-s", :desc => "The input for creating the package (Currently supported: #{supported_sources.join(', ')})", :required => true
13
+ method_option :target, :type => :string, :aliases => "-t", :desc => "The desired output format for the package (Currently supported: #{supported_targets.join(', ')})", :required => true
14
+ method_option :workdir, :type => :string, :aliases => "-wd", :desc => "A directory in which temporary files can be placed"
15
+ method_option :destination, :type => :string, :aliases => "-d", :desc => "The destination path where the application shall be installed to", :required => true
16
+ method_option :owner, :type => :string, :aliases => "-o", :desc => "The owning user for the destination path", :default => "root"
17
+ method_option :group, :type => :string, :aliases => "-g", :desc => "The owning group for the destination path", :default => "root"
18
+ method_option :buildnumber, :type => :string, :aliases => "-b", :desc => "The build number that is appended to the version", :required => false
11
19
 
12
20
  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"
21
+ raise "Only gem or bundler source at the moment" unless self.class.supported_sources.include? options.source
22
+ raise "Only deb target at the moment" unless self.class.supported_targets.include? options.target
15
23
  package_options = {}
16
- {:workdir => :work_dir , :destination => :destination}.each do |in_field, out_field|
24
+ {:workdir => :work_dir , :destination => :destination, :owner => :owner, :group => :group, :buildnumber => :build_number}.each do |in_field, out_field|
17
25
  package_options[out_field] = options[in_field] if options[in_field]
18
26
  end
19
27
 
20
28
  PackagingTask.create(file_or_directory, options.source, options.target, package_options).run
21
29
  end
22
30
 
23
- end
31
+ end
@@ -1,19 +1,24 @@
1
- class FilePathAndPermissions < Delegator
2
- attr_reader :permissions
3
- def initialize(path, permissions = "0444")
4
- @path = path
1
+ require 'delegate'
2
+ class FilePathAndPermissions < SimpleDelegator
3
+ attr_reader :permissions, :path
4
+ def initialize(path, permissions = 0444)
5
+ @path = path.to_s
6
+ super(@path)
5
7
  @permissions = permissions
6
8
  end
7
9
 
8
- def to_s
9
- @path
10
+ def eql?(other)
11
+ return @path == other if other.is_a? String
12
+ return @path == other.path if other.is_a? FilePathAndPermissions
13
+ super
10
14
  end
11
15
 
12
- def __getobj__
13
- @path
16
+ def inspect
17
+ vars = instance_variables.collect { |v| v.to_s << "=#{instance_variable_get(v).inspect}"}.join(", ")
18
+ "#<#{self.class}:#{vars}>"
14
19
  end
15
20
 
16
- def __setobj__(path)
17
- @path = path
21
+ def hash
22
+ @path.hash
18
23
  end
19
- end
24
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'file_path_and_permissions'
2
+ def write_file_contents(file_contents)
3
+ file_contents.each do |file_name, content|
4
+ FileUtils.mkdir_p(File.dirname(file_name))
5
+ File.open(file_name,"w") do |file|
6
+ file.print content
7
+ end
8
+ File.chmod(file_name.permissions, file_name.to_s) if file_name.is_a? FilePathAndPermissions
9
+ end
10
+ end
11
+
12
+ def write_file_contents_in_directory(file_contents,directory)
13
+ FileUtils.mkdir_p directory
14
+ Dir.chdir(directory) do
15
+ write_file_contents(file_contents)
16
+ end
17
+ end
18
+ def read_file_contents(files,base_directory)
19
+ file_contents = {}
20
+ files.each do |f|
21
+ path = File.join(base_directory,f)
22
+ permissions = File.lstat(path).mode % 4096
23
+ file_contents[FilePathAndPermissions.new(f,permissions)] = File.read(path) if File.file?(path)
24
+ end
25
+ file_contents
26
+ end
@@ -1,14 +1,23 @@
1
1
  class PackagingTask
2
- def self.create(file_or_directory, source_name, target_name, options = {})
3
- options[:work_dir] ||= Dir.mktmpdir
2
+
3
+ def self.class_for_source(source_name)
4
4
  require_relative "source"
5
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)
6
+ Kernel.const_get("Source").const_get(source_name.capitalize)
7
+ end
8
8
 
9
+ def self.class_for_target(target_name)
9
10
  require_relative "target"
10
11
  require_relative "target/#{target_name}"
11
- target_class = Kernel.const_get("Target").const_get(target_name.capitalize)
12
+ Kernel.const_get("Target").const_get(target_name.capitalize)
13
+ end
14
+
15
+ def self.create(file_or_directory, source_name, target_name, options = {})
16
+ options[:work_dir] ||= Dir.mktmpdir
17
+ source_class = class_for_source(source_name)
18
+ source = source_class.create(file_or_directory, options)
19
+
20
+ target_class = class_for_target(target_name)
12
21
  target = target_class.new(options[:work_dir], options)
13
22
  new(source,target)
14
23
  end
@@ -22,4 +31,4 @@ class PackagingTask
22
31
  @target.create_package(@source)
23
32
  end
24
33
 
25
- end
34
+ end
@@ -1,9 +1,12 @@
1
+ require 'pathname'
2
+ require_relative 'file_path_and_permissions'
3
+
1
4
  module Source
2
5
  class Base
3
6
  DEFAULTS = {
4
7
  # Default version is 1.0 in case nobody told us a specific version.
5
8
  :version => "1.0",
6
- :iteration => nil,
9
+ :build_number => nil,
7
10
  :epoch => nil,
8
11
  # If architecture is nil, the target package should provide a default.
9
12
  # Special 'architecture' values include "all" (aka rpm's noarch, debian's all)
@@ -46,10 +49,10 @@ module Source
46
49
  end
47
50
  end
48
51
  end
49
- end
50
- class FilesProvider
51
- def files
52
- file_contents.keys
52
+
53
+ def contains_file?(file_name)
54
+ file_name = FilePathAndPermissions.new(file_name) unless file_name.kind_of? FilePathAndPermissions
55
+ file_contents.include? file_name
53
56
  end
54
57
  end
55
- end
58
+ end
@@ -1,55 +1,26 @@
1
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
2
+ require_relative 'files_providers/files_from_bundler_directory_provider'
3
+ module Source
4
+ class Bundler < Source::Gem
5
+ def self.create(gemfile, options = {})
6
+ directory = File.absolute_path(File.dirname(gemfile))
7
+ gemspec = Dir[File.join(directory,'*.gemspec')].first
8
+ metadata = read_metadata(gemspec)
9
+
10
+ bundler_provider = FilesFromBundlerDirectoryProvider.new(File.expand_path(gemfile), gemspec)
11
+ package_path = File.join(directory, '_package_')
12
+ package_scripts_provider = Source::FilesFromDirectoryProvider.new(package_path, directory)
13
+ new(metadata, Source::CompositeFilesProvider.new(bundler_provider, package_scripts_provider), options)
14
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
15
+
16
+ def initialize(*args)
17
+ super
18
+ end
19
+ def architecture
20
+ "native"
21
+ end
22
+ def dependencies
23
+ ["libc6", "ruby"]
36
24
  end
37
25
  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
26
+ end
@@ -0,0 +1,23 @@
1
+ module Source
2
+ class CompositeFilesProvider
3
+ def initialize(*file_providers)
4
+ @file_providers = file_providers
5
+ end
6
+
7
+ def files
8
+ @file_providers.inject([]) do |merged, file_provider|
9
+ files = file_provider.files
10
+ raise "duplicate filename found in different file providers" unless (merged & files).empty?
11
+ merged + files
12
+ end
13
+ end
14
+
15
+ def file_contents
16
+ @file_providers.inject({}) do |merged, file_provider|
17
+ contents = file_provider.file_contents
18
+ raise "duplicate filename found in different file providers: #{(merged.keys & contents.keys)}" unless (merged.keys & contents.keys).empty?
19
+ merged.merge contents
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'files_from_directory_provider'
2
+ require_relative 'composite_files_provider'
3
+ require_relative 'files_from_gem_directory_provider'
4
+ require_relative 'vendored_gems_installer'
5
+ require_relative '../gem'
6
+ require 'bundler'
7
+
8
+ module Source
9
+ class FilesFromBundlerDirectoryProvider < FilesFromGemDirectoryProvider
10
+ attr_reader :gemfile,:gemspec
11
+ def initialize(gemfile,gemspec,vendored_gems_installer = nil)
12
+ raise "Must give me a Gemfile, not #{gemfile.inspect}" unless File.basename(gemfile)=="Gemfile"
13
+ metadata = Source::Gem.read_metadata(gemspec)
14
+ super(File.dirname(gemfile),metadata.files)
15
+ @gemfile = gemfile
16
+ @gemspec = gemspec
17
+ @vendored_gems_installer = vendored_gems_installer || Source::VendoredGemsInstaller.new(gemfile)
18
+ end
19
+
20
+ def bundled_files
21
+ files = nil
22
+ Dir.chdir(File.dirname(@gemfile)) do
23
+ files = Dir["vendor/bundle/**/*"]
24
+ end
25
+ files
26
+ end
27
+
28
+ def file_contents
29
+ @vendored_gems_installer.install!
30
+ super_contents = super.merge(read_file_contents(bundled_files+[File.basename(gemfile),File.basename(gemspec),'Gemfile.lock','.bundle/config'], directory))
31
+ super_contents
32
+ end
33
+
34
+
35
+ end
36
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'files_provider'
2
+
3
+ module Source
4
+ class FilesFromDirectoryProvider < FilesProvider
5
+ def initialize(directory=".", base_directory=nil)
6
+ @directory = directory
7
+ @base_directory = base_directory || directory
8
+ end
9
+
10
+ def file_contents
11
+ base_path = Pathname.new(@base_directory)
12
+ files = Dir[File.join(@directory, '**', '*')].collect {|file| Pathname.new(file).relative_path_from(base_path).to_s }
13
+ read_file_contents(files, @base_directory)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'files_provider'
2
+ module Source
3
+ class FilesFromGemDirectoryProvider < FilesProvider
4
+ attr_reader :directory
5
+ def initialize(directory,files)
6
+ @directory = directory
7
+ @files = files
8
+ end
9
+ def file_contents
10
+ read_file_contents @files, @directory
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ module Source
2
+ class FilesProvider
3
+ def files
4
+ file_contents.keys
5
+ end
6
+ def file_contents
7
+ {}
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ require_relative '../../file_path_and_permissions'
2
+
3
+ #This module is intended as a mixin, you still need to implement
4
+ # the respective methods, i.e.
5
+ # base_provider and permission_overrides
6
+ module OverridesPermissions
7
+ def file_contents
8
+ #Beware: Deep magic here.
9
+ result = base_provider.file_contents.map do |file_with_permissions,content|
10
+ _,override = permission_overrides.map do |condition,permission|
11
+ # Find the length of the longest match for the current regexp.
12
+ longest = file_with_permissions.scan(condition).map do |match|
13
+ match = match.join if match.kind_of? Array
14
+ match.length
15
+ end.max
16
+ # return the length of the longest match and the associated permission
17
+ # or nil if there was no match
18
+ [longest,permission] if longest
19
+ end.compact.max_by(&:first) #Get the Array with the greatest length in the first component.
20
+ file_with_permissions = FilePathAndPermissions.new(file_with_permissions,override) if override
21
+ [file_with_permissions,content]
22
+ end
23
+ Hash[*result.flatten]
24
+ end
25
+
26
+ def files
27
+ file_contents.keys
28
+ end
29
+
30
+ private
31
+ def base_provider
32
+ raise "Not implemented here. Override this method in the class that includes this module."
33
+ end
34
+ def permission_overrides
35
+ raise "Not implemented here. Override this method in the class that includes this module."
36
+ end
37
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'files_provider'
2
+
3
+ module Source
4
+ class VendoredGemsInstaller
5
+ attr_reader :gemfile
6
+ def initialize(gemfile)
7
+ @gemfile = gemfile
8
+ @installed = false
9
+ end
10
+ def directory
11
+ File.dirname(@gemfile)
12
+ end
13
+ def install!
14
+ return if @installed
15
+ backup_fields = ["PATH","GEM_PATH"]
16
+ bundled_files = []
17
+
18
+ old_env = ENV.to_hash
19
+ Dir.chdir(directory) do
20
+ ::Bundler.with_clean_env do
21
+ old_env.each {|k,_| ENV.delete k}
22
+ ENV["BUNDLE_GEMFILE"] = gemfile
23
+ ENV["PWD"] = directory
24
+ backup_fields.each {|f| ENV[f] = old_env[f]}
25
+ FileUtils.rm_rf('.bundle')
26
+ ["bundle install","bundle install --deployment --verbose"].each do |c| # --standalone
27
+ command_result = `#{c}`
28
+ raise "#{c.inspect} failed:\n#{command_result}" unless $?.success?
29
+ end
30
+ end
31
+ end
32
+ old_env.each {|k,v| ENV[k] = v}
33
+ @installed = true
34
+ end
35
+ end
36
+ end
@@ -1,9 +1,11 @@
1
1
  require_relative '../source'
2
+ require_relative 'files_providers/files_from_gem_directory_provider'
2
3
  require "rubygems/package"
3
4
  require "rubygems"
4
5
  require 'zlib'
5
6
 
6
- class Source::Gem < Source::Base
7
+ module Source
8
+ class Gem < Base
7
9
  class FilesFromGemProvider < Source::FilesProvider
8
10
  def initialize(contents)
9
11
  @gem_file_contents = contents
@@ -17,7 +19,7 @@ class Source::Gem < Source::Base
17
19
  contents
18
20
  end
19
21
  def tar_files(io)
20
- tar_reader = Gem::Package::TarReader.new(io)
22
+ tar_reader = ::Gem::Package::TarReader.new(io)
21
23
  tar_files = {}
22
24
  tar_reader.each do |entry|
23
25
  tar_files[entry.full_name] = entry.read
@@ -27,24 +29,6 @@ class Source::Gem < Source::Base
27
29
  end
28
30
  end
29
31
 
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
32
 
49
33
  def self.read_metadata(gem_file)
50
34
  metadata = nil
@@ -58,13 +42,16 @@ class Source::Gem < Source::Base
58
42
  end
59
43
  end
60
44
  elsif gem_file.end_with?('.gemspec')
61
- metadata = Gem::Specification.load(gem_file)
45
+ metadata = ::Gem::Specification.load(gem_file)
46
+ else
47
+ raise "Unknown file type of #{gem_file}. Need a .gem or .gemspec file"
62
48
  end
63
49
  end
50
+ raise "Could not read metadata for #{gem_file.inspect}" unless metadata
64
51
  metadata
65
52
  end
66
53
 
67
- def self.create(gem_file)
54
+ def self.create(gem_file, options = {})
68
55
  metadata = self.read_metadata(gem_file)
69
56
 
70
57
  files_provider = nil
@@ -77,13 +64,14 @@ class Source::Gem < Source::Base
77
64
  files_provider = FilesFromGemDirectoryProvider.new(File.expand_path(File.dirname(gem_file)), metadata.files+[File.basename(gem_file)])
78
65
  end
79
66
  end
80
- new(metadata, files_provider)
67
+ new(metadata, files_provider, options)
81
68
  end
82
69
 
83
70
  attr_reader :metadata, :files_provider
84
- def initialize(metadata, files_provider = nil)
71
+ def initialize(metadata, files_provider = nil, options = {})
85
72
  @metadata = metadata
86
73
  @files_provider = files_provider
74
+ @options = options
87
75
  end
88
76
 
89
77
  %w(description license summary version email).each do |method|
@@ -91,6 +79,12 @@ class Source::Gem < Source::Base
91
79
  metadata.send(method)
92
80
  end
93
81
  end
82
+
83
+ %w(owner group destination build_number).each do |method|
84
+ define_method method do
85
+ @options[method.to_sym]
86
+ end
87
+ end
94
88
  {:maintainer => :author, :url => :homepage}.each do |out_field, in_field|
95
89
  define_method out_field do
96
90
  metadata.send(in_field)
@@ -132,12 +126,13 @@ class Source::Gem < Source::Base
132
126
  dependencies << "#{name(dep)} #{req}"
133
127
  end
134
128
  end
135
- dependencies
129
+ return dependencies + ["libc6", "ruby"]
136
130
  end
137
131
  def file_contents
138
- @files_provider.nil? ? {} : @files_provider.file_contents
132
+ files_provider.nil? ? {} : files_provider.file_contents
139
133
  end
140
134
  def files
141
- @files_provider.files
135
+ files_provider.files
142
136
  end
137
+ end
143
138
  end
@@ -7,6 +7,7 @@ require_relative 'file_path_and_permissions'
7
7
 
8
8
  require_relative 'target/generate_from_templates'
9
9
  require_relative 'target/zip_directories'
10
+ require_relative 'io_helpers'
10
11
  module Target
11
12
  class Base
12
13
  PHASES = [:file_creation, :packaging]
@@ -19,6 +20,9 @@ module Target
19
20
  def self.steps_for_phase(phase)
20
21
  self.send(field_name_for_steps(phase))
21
22
  end
23
+ def self.add_step_for_phase(phase, block, description = nil)
24
+ steps_for_phase(phase) << [block, description]
25
+ end
22
26
  class_inheritable_array *phase_steps_names
23
27
  phase_steps_names.each {|p| self.send("#{p}=".to_sym,[])}
24
28
 
@@ -28,6 +32,7 @@ module Target
28
32
  def initialize(work_dir, options = {})
29
33
  @work_dir = work_dir
30
34
  @logger = ::Logger.new(STDERR)
35
+ @logger.level = ::Logger::INFO
31
36
  @options = options
32
37
  end
33
38
 
@@ -43,30 +48,16 @@ module Target
43
48
  @origin_dir = Dir.getwd
44
49
  FileUtils.mkdir_p package_dir
45
50
  ::Dir.chdir(package_dir) do
46
- self.class.phase_steps_names.each do |steps|
47
- self.class.send(steps).each do |step|
51
+ self.class.phase_steps_names.each do |phase_name|
52
+ steps_for_phase = self.class.send(phase_name)
53
+ steps_for_phase.each do |step, description|
54
+ @logger.info description if description
48
55
  instance_exec source, &step
49
56
  end
50
57
  end
51
58
  end
52
59
  end
53
60
 
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
61
 
71
62
  def tar_directory(directory, options = {})
72
63
  FileUtils.mkdir_p(directory)
@@ -80,9 +71,9 @@ module Target
80
71
  end
81
72
 
82
73
  def exec(*args)
83
- puts args.join(" ")
74
+ @logger.debug args.join(" ")
84
75
  success = system(*args)
85
- puts "#{args.join(" ")} did not complete successfully!" unless success
76
+ @logger.error "#{args.join(" ")} did not complete successfully!" unless success
86
77
  end
87
78
  end
88
79
  end
@@ -1,23 +1,47 @@
1
1
  require_relative '../target'
2
+ require_relative '../source'
3
+ require_relative '../source/files_providers/overrides_permissions'
2
4
  require 'erb'
3
5
  require 'delegate'
4
6
  require_relative 'step_plugin'
5
7
 
6
8
  class Target::Deb < Target::Base
7
9
  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)
10
+ POST_INST_FILES = /^_package_\/postinst.*$/
11
+ PRE_RM_FILES = /^_package_\/prerm.*$/
12
+ SCRIPT_PERMISSIONS = 0750
13
+
14
+ def self.architecture(architecture=nil)
15
+ if architecture.nil? or architecture == "native"
16
+ # Default architecture should be 'native' which we'll need
17
+ # to ask the system about.
18
+ arch = %x{dpkg --print-architecture}.chomp
19
+ if $?.exitstatus != 0
20
+ arch = %x{uname -m}.chomp
21
+ @logger.warn("Can't find 'dpkg' tool (need it to get default " \
22
+ "architecture!). Please specificy --architecture " \
23
+ "specifically. (Defaulting now to #{arch})")
24
+ end
25
+ arch
26
+ elsif architecture == "x86_64"
27
+ # Debian calls x86_64 "amd64"
28
+ "amd64"
29
+ else
30
+ architecture
13
31
  end
32
+ end
14
33
 
15
- def __getobj__
16
- @delegate_sd_obj # return object we are delegating to, required
34
+ class DebianSourceWrapper < SimpleDelegator
35
+ include OverridesPermissions
36
+ alias :base_provider :__getobj__
37
+ def initialize(source)
38
+ raise("nil source") unless source
39
+ super(source)
40
+ @logger = ::Logger.new(STDERR)
17
41
  end
18
42
 
19
- def __setobj__(source)
20
- @delegate_sd_obj = source # change delegation object, a feature we're providing
43
+ def permission_overrides
44
+ { Regexp.union(POST_INST_FILES, PRE_RM_FILES) => SCRIPT_PERMISSIONS }
21
45
  end
22
46
 
23
47
  def name
@@ -33,7 +57,7 @@ class Target::Deb < Target::Base
33
57
  end
34
58
 
35
59
  if name.include?("_")
36
- @logger.info("Package name '#{name}' includes underscores, converting" \
60
+ @logger.debug("Package name '#{name}' includes underscores, converting" \
37
61
  " to dashes")
38
62
  name = name.gsub(/[_]/, "-")
39
63
  end
@@ -41,31 +65,14 @@ class Target::Deb < Target::Base
41
65
  return name
42
66
  end
43
67
  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
68
+ Target::Deb.architecture(__getobj__.architecture)
62
69
  end # def architecture
63
70
 
64
71
  def default_output
65
72
  name_and_version = "#{name}_#{version}"
66
73
  architecture_and_type = "#{architecture}.#{type}"
67
- if iteration
68
- "#{name_and_version}-#{iteration}_#{architecture_and_type}"
74
+ if build_number
75
+ "#{name_and_version}-b#{build_number}_#{architecture_and_type}"
69
76
  else
70
77
  "#{name_and_version}_#{architecture_and_type}"
71
78
  end
@@ -95,8 +102,8 @@ class Target::Deb < Target::Base
95
102
  nextversion[l-1] = 0
96
103
  nextversion = nextversion.join(".")
97
104
  return ["#{name} (>= #{version})", "#{name} (<< #{nextversion})"]
98
- # ignore iterations for = dependencies if flag specified
99
- elsif (m = dep.match(/(\S+)\s+\(= (.+)\)/)) && self.settings[:ignore_iteration]
105
+ # ignore build_numbers for = dependencies if flag specified
106
+ elsif (m = dep.match(/(\S+)\s+\(= (.+)\)/)) && self.settings[:ignore_build_numbers]
100
107
  name, version = m[1..2]
101
108
  nextversion = version.split('.').collect { |v| v.to_i }
102
109
  nextversion[-1] += 1
@@ -115,10 +122,11 @@ class Target::Deb < Target::Base
115
122
  Dir["**/*.so"]
116
123
  end
117
124
 
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) }
125
+ in_phase(:file_creation, "Stripping links from binaries...") { exec("strip --strip-unneeded #{all_binaries.join(' ')}") unless all_binaries.empty? }
126
+ in_phase(:file_creation, "Removing absolute paths from binaries...") { exec("chrpath --delete #{all_binaries.join(' ')}") unless all_binaries.empty? }
127
+ in_phase(:file_creation, "Making files unwriteable by group and others...") { exec("chmod -R go-w *") }
128
+ in_phase(:packaging, "Packaging metafiles and files into .deb package...") {|source| exec("ar -qc ../#{source.default_output} debian-binary control.tar.gz data.tar.gz") }
129
+ in_phase(:packaging, "Copying .deb package to output directory...") {|source| FileUtils.cp("../#{source.default_output}",@origin_dir) }
122
130
 
123
131
  def create_package(source)
124
132
  super(DebianSourceWrapper.new(source))
@@ -2,7 +2,7 @@ require_relative 'step_plugin'
2
2
  require_relative '../file_path_and_permissions'
3
3
  module GenerateFromTemplates
4
4
  include StepPlugin
5
- in_phase(:file_creation) { |source| write_files_to_package_dir(source) }
5
+ in_phase(:file_creation, "Expanding templates...") { |source| write_files_to_package_dir(source) }
6
6
 
7
7
  def template_paths
8
8
  @template_paths ||= Dir["#{template_dir}/**/*.erb"]
@@ -1,19 +1,20 @@
1
1
  module StepPlugin
2
2
  def self.included(base)
3
3
  if base.is_a? Class
4
- def base.in_phase(phase, &block)
5
- self.steps_for_phase(phase) << block
4
+ def base.in_phase(phase, description=nil, &block)
5
+ self.add_step_for_phase(phase,block,description)
6
6
  end
7
7
  elsif base.is_a? Module
8
- def base.in_phase(phase, &block)
8
+ def base.in_phase(phase, description=nil, &block)
9
9
  @phase_blocks||= {}
10
10
  @phase_blocks[phase] ||= []
11
- @phase_blocks[phase] << block
11
+ @phase_blocks[phase] << [block, description]
12
12
  end
13
13
  def base.included(clazz)
14
14
  @phase_blocks.each do |phase, blocks|
15
- blocks.each do |block|
16
- clazz.steps_for_phase(phase) << block
15
+ blocks.each do |block_and_description|
16
+ block, description = block_and_description
17
+ clazz.add_step_for_phase(phase,block,description)
17
18
  end
18
19
  end
19
20
  end
@@ -1,7 +1,7 @@
1
1
  require_relative 'step_plugin'
2
2
  module ZipDirectories
3
3
  include StepPlugin
4
- in_phase(:packaging) do
4
+ in_phase(:packaging, "Zipping directories...") do
5
5
  Dir["*.tar.gz.dir"].each do |tar_gz_dir|
6
6
  tar_directory(tar_gz_dir, :group=>"root",:owner=>"root")
7
7
  end
@@ -1,5 +1,5 @@
1
1
  Package: <%= name %>
2
- Version: <%= "#{epoch}:" if epoch %><%= version %><%= iteration && '-'+iteration.to_s %>
2
+ Version: <%= "#{epoch}:" if epoch %><%= version %><%= build_number && '-b'+build_number.to_s %>
3
3
  Architecture: <%= architecture %>
4
4
  Maintainer: <%= maintainer or "<unknown>" %><%= " <#{email}>".gsub(" <>","") %>
5
5
  <% if !dependencies.empty? -%>
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+ set -e
3
+ chown <%= owner %>:<%= group %> -R <%= destination %>
4
+ <% file_contents.keys.select { |file| file =~ Target::Deb::POST_INST_FILES }.sort.each do |file| %><%= File.join(destination, file) %> $*
5
+ <% end %>
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+ set -e
3
+ <% file_contents.keys.select { |file| file =~ Target::Deb::PRE_RM_FILES }.sort.each do |file| %><%= File.join(destination, file) %> $*
4
+ <% end %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.3
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-08-16 00:00:00.000000000Z
12
+ date: 2011-09-14 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
16
- requirement: &78034030 !ruby/object:Gem::Requirement
16
+ requirement: &75731240 !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: :runtime
23
23
  prerelease: false
24
- version_requirements: *78034030
24
+ version_requirements: *75731240
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: thor
27
- requirement: &78033470 !ruby/object:Gem::Requirement
27
+ requirement: &75730810 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.14.6
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *78033470
35
+ version_requirements: *75730810
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: activesupport
38
- requirement: &78033080 !ruby/object:Gem::Requirement
38
+ requirement: &75730540 !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: :runtime
45
45
  prerelease: false
46
- version_requirements: *78033080
46
+ version_requirements: *75730540
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: i18n
49
- requirement: &78032450 !ruby/object:Gem::Requirement
49
+ requirement: &75730250 !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: *78032450
57
+ version_requirements: *75730250
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: cucumber
60
- requirement: &78031940 !ruby/object:Gem::Requirement
60
+ requirement: &75729940 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.0.2
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *78031940
68
+ version_requirements: *75729940
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: aruba
71
- requirement: &78025220 !ruby/object:Gem::Requirement
71
+ requirement: &75729620 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,32 +76,32 @@ dependencies:
76
76
  version: 0.4.3
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *78025220
79
+ version_requirements: *75729620
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: guard
82
- requirement: &78024410 !ruby/object:Gem::Requirement
82
+ requirement: &75729360 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
86
86
  - !ruby/object:Gem::Version
87
- version: 0.5.1
87
+ version: 0.7.0
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *78024410
90
+ version_requirements: *75729360
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: guard-cucumber
93
- requirement: &78023540 !ruby/object:Gem::Requirement
93
+ requirement: &75729110 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ~>
97
97
  - !ruby/object:Gem::Version
98
- version: 0.5.2
98
+ version: 0.6.3
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *78023540
101
+ version_requirements: *75729110
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: guard-bundler
104
- requirement: &78022860 !ruby/object:Gem::Requirement
104
+ requirement: &75728810 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,18 +109,40 @@ dependencies:
109
109
  version: 0.1.3
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *78022860
112
+ version_requirements: *75728810
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: guard-rspec
115
- requirement: &78022250 !ruby/object:Gem::Requirement
115
+ requirement: &75728460 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ~>
119
119
  - !ruby/object:Gem::Version
120
- version: 0.4.0
120
+ version: 0.4.5
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *78022250
123
+ version_requirements: *75728460
124
+ - !ruby/object:Gem::Dependency
125
+ name: fakefs
126
+ requirement: &75728070 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: 0.3.2
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *75728070
135
+ - !ruby/object:Gem::Dependency
136
+ name: simplecov
137
+ requirement: &75727760 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ~>
141
+ - !ruby/object:Gem::Version
142
+ version: 0.4.2
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: *75727760
124
146
  description: Convert directories, rpms, python eggs, rubygems, and more to rpms, debs,
125
147
  solaris packages and more. Win at package management without wasting pointless hours
126
148
  debugging bad rpm specs!
@@ -131,21 +153,32 @@ extensions: []
131
153
  extra_rdoc_files: []
132
154
  files:
133
155
  - lib/gpm/cli.rb
156
+ - lib/gpm/source/files_providers/composite_files_provider.rb
157
+ - lib/gpm/source/files_providers/files_from_gem_directory_provider.rb
158
+ - lib/gpm/source/files_providers/overrides_permissions.rb
159
+ - lib/gpm/source/files_providers/vendored_gems_installer.rb
160
+ - lib/gpm/source/files_providers/files_from_bundler_directory_provider.rb
161
+ - lib/gpm/source/files_providers/files_from_directory_provider.rb
162
+ - lib/gpm/source/files_providers/files_provider.rb
134
163
  - lib/gpm/source/bundler.rb
135
164
  - lib/gpm/source/gem.rb
136
165
  - lib/gpm/packaging_task.rb
137
166
  - lib/gpm/file_path_and_permissions.rb
138
167
  - lib/gpm/target.rb
139
168
  - lib/gpm/source.rb
169
+ - lib/gpm/io_helpers.rb
140
170
  - lib/gpm/target/generate_from_templates.rb
141
171
  - lib/gpm/target/deb.rb
142
172
  - lib/gpm/target/zip_directories.rb
143
173
  - lib/gpm/target/step_plugin.rb
174
+ - bin/correct_permissions
144
175
  - bin/gpm
145
176
  - 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
177
+ - templates/deb/data.tar.gz.dir/usr/share/doc/__name__/changelog.Debian.gz.erb
147
178
  - templates/deb/control.tar.gz.dir/md5sums.erb
179
+ - templates/deb/control.tar.gz.dir/postinst.erb
148
180
  - templates/deb/control.tar.gz.dir/control.erb
181
+ - templates/deb/control.tar.gz.dir/prerm.erb
149
182
  - templates/deb/debian-binary.erb
150
183
  homepage: https://github.com/crealytics/gpm
151
184
  licenses: []