Cross package maker. DEB/RPM generation or conversion. Derived from jordansissel/fpm.

⌈⌋ ⎇ branch:  cross package maker


Check-in [9111aeaef0]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:- Add gem packaging
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9111aeaef037ac852d80754167ff57bf168c6648
User & Date: jls@semicomplete.com 2011-01-04 01:25:06
Context
2011-01-04
02:22
- Fix gem-ification bits (now installs+runs) - Factor out 'deb' package assembly into a library check-in: 9f16bb5dd3 user: jls@semicomplete.com tags: trunk
01:25
- Add gem packaging check-in: 9111aeaef0 user: jls@semicomplete.com tags: trunk
2011-01-03
23:42
- rename to fpm. check-in: 9712ba37db user: jls@semicomplete.com tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Added Rakefile.



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
task :default => [:package]

task :test do
  system("cd test; ruby alltests.rb")
end

task :package => [:test, :package_real]  do
end

task :package_real do
  system("gem build fpm.gemspec")
end

task :publish do
  latest_gem = %x{ls -t fpm*.gem}.split("\n").first
  system("gem push #{latest_gem}")
end

Added bin/fpm.





























































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env ruby
#

require "optparse"
require "ostruct"
require "erb"

def main(args)
  settings = OpenStruct.new

  opts = OptionParser.new do |opts|
    opts.banner = "Usage: #{$0} [options]"
    
    opts.on("-p PACKAGEFILE", "--package PACKAGEFILE",
            "The package file to manage") do |path|
      if path =~ /^\//
        settings.package_path = path
      else
        settings.package_path = "#{Dir.pwd}/#{path}"
      end
    end

    opts.on("-n PACKAGENAME", "--name PACKAGENAME",
            "What name to give to the package") do |name|
      settings.package_name = name
    end

    opts.on("-v VERSION", "--version VERSION",
            "version to give the package") do |version|
      settings.version = version
    end

    opts.on("-d DEPENDENCY", "--depends DEPENDENCY") do |dep|
      settings.dependencies ||= []
      settings.dependencies << dep
    end

    opts.on("-a ARCHITECTURE", "--architecture ARCHITECTURE") do |arch|
      settings.architecture = arch
    end

    opts.on("-m MAINTAINER", "--maintainer MAINTAINER") do |maintainer|
      settings.maintainer = maintainer
    end

    opts.on("-C DIRECTORY", "Change directory before searching for files") do |dir|
      settings.chdir = dir
    end
  end # OptionParser

  opts.parse!(args)

  # Actions:
  # create package
  #
  # files: add, remove
  # scripts: add, remove
  # metadata: set, add, remove

  if !settings.package_path
    $stderr.puts "No package file given to manage. Give with -p PACKAGEFILE"
    return 1
  end

  paths = args
  type = settings.package_path.split(".")[-1]

  mkbinding = lambda do
    package = settings.package_name
    version = settings.version
    package_iteration = 1

    maintainer = (settings.maintainer or "<#{ENV["USER"]}>")
    category = (settings.category or "X11")
    summary = (settings.summary or "no summary given for #{package}-#{version}")

    architecture = (settings.architecture or %x(uname -m).chomp)
    if architecture == "x86_64" && type == "deb"
      architecture = "amd64"
    end


    url = (settings.url or "http://example.com/")
    dependencies = (settings.dependencies or [])
    return binding
  end

  metadata = mkbinding.call

  package_path = settings.package_path
  package_path.gsub!(/VERSION/, eval('"#{version}-#{package_iteration}"', metadata))
  package_path.gsub!(/ARCH/, eval("architecture", metadata))


  if type != "deb"
    $stderr.puts "Unsupported package type '#{type}'"
    return 1
  end


  builddir = "#{Dir.pwd}/build-#{type}-#{File.basename(package_path)}"
  Dir.mkdir(builddir) if !File.directory?(builddir)
  template = File.new("#{File.dirname(__FILE__)}/../templates/#{type}.erb").read()

  Dir.chdir(settings.chdir || ".") do 
    puts Dir.pwd

    # Add directories first.
    dirs = []
    paths.each do |path|
      while path != "/" and path != "."
        if !dirs.include?(path) or File.symlink?(path)
          dirs << path 
        else
          #puts "Skipping: #{path}"
          #puts !dirs.include?(path) 
          #puts !File.symlink?(path)
        end
        path = File.dirname(path)
      end
    end
    dirs = dirs.sort { |a,b| a.length <=> b.length}
    puts dirs.join("\n")
    system(*["tar", "--owner=root", "--group=root", "-cf", "#{builddir}/data.tar", "--no-recursion", *dirs])
    puts paths.join("\n")
    #paths = paths.reject { |p| File.symlink?(p) }
    system(*["tar", "--owner=root", "--group=root", "-rf", "#{builddir}/data.tar", *paths])
    system(*["gzip", "-f", "#{builddir}/data.tar"])

    # Generate md5sums
    md5sums = []
    paths.each do |path|
      md5sums += %x{find #{path} -type f -print0 | xargs -0 md5sum}.split("\n")
    end
    File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums.join("\n") }

    # Generate 'control' file
    control = ERB.new(template).result(metadata)
    File.open("#{builddir}/control", "w") { |f| f.puts control }
  end

  # create control.tar.gz
  Dir.chdir(builddir) do
    system("tar -zcf control.tar.gz control md5sums")
  end

  Dir.chdir(builddir) do
    # create debian-binary
    File.open("debian-binary", "w") { |f| f.puts "2.0" }
  end

  Dir.chdir(builddir) do
    system("ar -qc #{package_path} debian-binary control.tar.gz data.tar.gz")
  end
end

ret = main(ARGV) 
exit(ret != nil ? ret : 0)

Deleted bin/fpm.rb.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/env ruby
#

require "optparse"
require "ostruct"
require "erb"

def main(args)
  settings = OpenStruct.new

  opts = OptionParser.new do |opts|
    opts.banner = "Usage: #{$0} [options]"
    
    opts.on("-p PACKAGEFILE", "--package PACKAGEFILE",
            "The package file to manage") do |path|
      if path =~ /^\//
        settings.package_path = path
      else
        settings.package_path = "#{Dir.pwd}/#{path}"
      end
    end

    opts.on("-n PACKAGENAME", "--name PACKAGENAME",
            "What name to give to the package") do |name|
      settings.package_name = name
    end

    opts.on("-v VERSION", "--version VERSION",
            "version to give the package") do |version|
      settings.version = version
    end

    opts.on("-d DEPENDENCY", "--depends DEPENDENCY") do |dep|
      settings.dependencies ||= []
      settings.dependencies << dep
    end

    opts.on("-a ARCHITECTURE", "--architecture ARCHITECTURE") do |arch|
      settings.architecture = arch
    end

    opts.on("-m MAINTAINER", "--maintainer MAINTAINER") do |maintainer|
      settings.maintainer = maintainer
    end

    opts.on("-C DIRECTORY", "Change directory before searching for files") do |dir|
      settings.chdir = dir
    end
  end # OptionParser

  opts.parse!(args)

  # Actions:
  # create package
  #
  # files: add, remove
  # scripts: add, remove
  # metadata: set, add, remove

  if !settings.package_path
    $stderr.puts "No package file given to manage. Give with -p PACKAGEFILE"
    return 1
  end

  paths = args
  type = settings.package_path.split(".")[-1]

  mkbinding = lambda do
    package = settings.package_name
    version = settings.version
    package_iteration = 1

    maintainer = (settings.maintainer or "<#{ENV["USER"]}>")
    category = (settings.category or "X11")
    summary = (settings.summary or "no summary given for #{package}-#{version}")

    architecture = (settings.architecture or %x(uname -m).chomp)
    if architecture == "x86_64" && type == "deb"
      architecture = "amd64"
    end


    url = (settings.url or "http://example.com/")
    dependencies = (settings.dependencies or [])
    return binding
  end

  metadata = mkbinding.call

  package_path = settings.package_path
  package_path.gsub!(/VERSION/, eval('"#{version}-#{package_iteration}"', metadata))
  package_path.gsub!(/ARCH/, eval("architecture", metadata))


  if type != "deb"
    $stderr.puts "Unsupported package type '#{type}'"
    return 1
  end


  builddir = "#{Dir.pwd}/build-#{type}-#{File.basename(package_path)}"
  Dir.mkdir(builddir) if !File.directory?(builddir)
  template = File.new("#{File.dirname(__FILE__)}/../templates/#{type}.erb").read()

  Dir.chdir(settings.chdir || ".") do 
    puts Dir.pwd

    # Add directories first.
    dirs = []
    paths.each do |path|
      while path != "/" and path != "."
        if !dirs.include?(path) or File.symlink?(path)
          dirs << path 
        else
          #puts "Skipping: #{path}"
          #puts !dirs.include?(path) 
          #puts !File.symlink?(path)
        end
        path = File.dirname(path)
      end
    end
    dirs = dirs.sort { |a,b| a.length <=> b.length}
    puts dirs.join("\n")
    system(*["tar", "--owner=root", "--group=root", "-cf", "#{builddir}/data.tar", "--no-recursion", *dirs])
    puts paths.join("\n")
    #paths = paths.reject { |p| File.symlink?(p) }
    system(*["tar", "--owner=root", "--group=root", "-rf", "#{builddir}/data.tar", *paths])
    system(*["gzip", "-f", "#{builddir}/data.tar"])

    # Generate md5sums
    md5sums = []
    paths.each do |path|
      md5sums += %x{find #{path} -type f -print0 | xargs -0 md5sum}.split("\n")
    end
    File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums.join("\n") }

    # Generate 'control' file
    control = ERB.new(template).result(metadata)
    File.open("#{builddir}/control", "w") { |f| f.puts control }
  end

  # create control.tar.gz
  Dir.chdir(builddir) do
    system("tar -zcf control.tar.gz control md5sums")
  end

  Dir.chdir(builddir) do
    # create debian-binary
    File.open("debian-binary", "w") { |f| f.puts "2.0" }
  end

  Dir.chdir(builddir) do
    system("ar -qc #{package_path} debian-binary control.tar.gz data.tar.gz")
  end
end

ret = main(ARGV) 
exit(ret != nil ? ret : 0)
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




























































































































































































































































































































Added fpm.gemspec.















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Gem::Specification.new do |spec|
  files = []
  dirs = %w{lib bin}
  dirs.each do |dir|
    files += Dir["#{dir}/**/*"]
  end

  rev = Time.now.strftime("%Y%m%d%H%M%S")
  spec.name = "fpm"
  spec.version = "0.1.0"
  spec.summary = "fpm - package building and mangling"
  spec.description = "Turn directories into packages. Fix broken packages. Win the package management game."
  spec.add_dependency("json")
  spec.files = files
  spec.require_paths << "lib"
  spec.bindir = "bin"
  spec.executables << "fpm"

  spec.author = "Jordan Sissel"
  spec.email = "jls@semicomplete.com"
  spec.homepage = "https://github.com/jordansissel/fpm"
end