Skip to content
This repository
Browse code

- Fix gem-ification bits (now installs+runs)

- Factor out 'deb' package assembly into a library
  • Loading branch information...
commit 5b942f27106eb8965460c6835eacf5026d0abbca 1 parent 63494e9
Jordan Sissel authored
112 bin/fpm 100644 → 100755
... ... @@ -1,9 +1,11 @@
1 1 #!/usr/bin/env ruby
2 2 #
3 3
  4 +require "rubygems"
4 5 require "optparse"
5 6 require "ostruct"
6 7 require "erb"
  8 +require "fpm"
7 9
8 10 def main(args)
9 11 settings = OpenStruct.new
@@ -11,6 +13,7 @@ def main(args)
11 13 opts = OptionParser.new do |opts|
12 14 opts.banner = "Usage: #{$0} [options]"
13 15
  16 + # TODO(sissel): Maybe this should be '-o OUTPUT' ?
14 17 opts.on("-p PACKAGEFILE", "--package PACKAGEFILE",
15 18 "The package file to manage") do |path|
16 19 if path =~ /^\//
@@ -50,109 +53,22 @@ def main(args)
50 53
51 54 opts.parse!(args)
52 55
53   - # Actions:
54   - # create package
55   - #
56   - # files: add, remove
57   - # scripts: add, remove
58   - # metadata: set, add, remove
59   -
60 56 if !settings.package_path
61 57 $stderr.puts "No package file given to manage. Give with -p PACKAGEFILE"
62 58 return 1
63 59 end
64 60
65   - paths = args
66   - type = settings.package_path.split(".")[-1]
67   -
68   - mkbinding = lambda do
69   - package = settings.package_name
70   - version = settings.version
71   - package_iteration = 1
72   -
73   - maintainer = (settings.maintainer or "<#{ENV["USER"]}>")
74   - category = (settings.category or "X11")
75   - summary = (settings.summary or "no summary given for #{package}-#{version}")
76   -
77   - architecture = (settings.architecture or %x(uname -m).chomp)
78   - if architecture == "x86_64" && type == "deb"
79   - architecture = "amd64"
80   - end
81   -
82   -
83   - url = (settings.url or "http://example.com/")
84   - dependencies = (settings.dependencies or [])
85   - return binding
86   - end
87   -
88   - metadata = mkbinding.call
89   -
90   - package_path = settings.package_path
91   - package_path.gsub!(/VERSION/, eval('"#{version}-#{package_iteration}"', metadata))
92   - package_path.gsub!(/ARCH/, eval("architecture", metadata))
93   -
94   -
95   - if type != "deb"
96   - $stderr.puts "Unsupported package type '#{type}'"
97   - return 1
98   - end
99   -
100   -
101   - builddir = "#{Dir.pwd}/build-#{type}-#{File.basename(package_path)}"
102   - Dir.mkdir(builddir) if !File.directory?(builddir)
103   - template = File.new("#{File.dirname(__FILE__)}/../templates/#{type}.erb").read()
104   -
105   - Dir.chdir(settings.chdir || ".") do
106   - puts Dir.pwd
107   -
108   - # Add directories first.
109   - dirs = []
110   - paths.each do |path|
111   - while path != "/" and path != "."
112   - if !dirs.include?(path) or File.symlink?(path)
113   - dirs << path
114   - else
115   - #puts "Skipping: #{path}"
116   - #puts !dirs.include?(path)
117   - #puts !File.symlink?(path)
118   - end
119   - path = File.dirname(path)
120   - end
121   - end
122   - dirs = dirs.sort { |a,b| a.length <=> b.length}
123   - puts dirs.join("\n")
124   - system(*["tar", "--owner=root", "--group=root", "-cf", "#{builddir}/data.tar", "--no-recursion", *dirs])
125   - puts paths.join("\n")
126   - #paths = paths.reject { |p| File.symlink?(p) }
127   - system(*["tar", "--owner=root", "--group=root", "-rf", "#{builddir}/data.tar", *paths])
128   - system(*["gzip", "-f", "#{builddir}/data.tar"])
129   -
130   - # Generate md5sums
131   - md5sums = []
132   - paths.each do |path|
133   - md5sums += %x{find #{path} -type f -print0 | xargs -0 md5sum}.split("\n")
134   - end
135   - File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums.join("\n") }
136   -
137   - # Generate 'control' file
138   - control = ERB.new(template).result(metadata)
139   - File.open("#{builddir}/control", "w") { |f| f.puts control }
140   - end
141   -
142   - # create control.tar.gz
143   - Dir.chdir(builddir) do
144   - system("tar -zcf control.tar.gz control md5sums")
145   - end
146   -
147   - Dir.chdir(builddir) do
148   - # create debian-binary
149   - File.open("debian-binary", "w") { |f| f.puts "2.0" }
150   - end
151   -
152   - Dir.chdir(builddir) do
153   - system("ar -qc #{package_path} debian-binary control.tar.gz data.tar.gz")
154   - end
155   -end
  61 + package = FPM::Deb.new
  62 + package.name = settings.package_name
  63 + package.version = settings.version
  64 + package.maintainer = settings.maintainer if settings.maintainer
  65 + package.architecture = settings.architecture or %x{uname -m}.chomp
  66 + package.assemble({
  67 + "output" => settings.package_path,
  68 + "root" => settings.chdir,
  69 + "paths" => args, # Remainder of args are paths.
  70 + })
  71 +end # def main
156 72
157 73 ret = main(ARGV)
158 74 exit(ret != nil ? ret : 0)
2  fpm.gemspec
... ... @@ -1,6 +1,6 @@
1 1 Gem::Specification.new do |spec|
2 2 files = []
3   - dirs = %w{lib bin}
  3 + dirs = %w{lib bin templates}
4 4 dirs.each do |dir|
5 5 files += Dir["#{dir}/**/*"]
6 6 end
3  lib/fpm.rb
... ... @@ -0,0 +1,3 @@
  1 +require "fpm/namespace"
  2 +require "fpm/package"
  3 +require "fpm/deb"
74 lib/fpm/deb.rb
... ... @@ -0,0 +1,74 @@
  1 +#!/usr/bin/env ruby
  2 +#
  3 +
  4 +require "erb"
  5 +require "fpm/namespace"
  6 +require "fpm/package"
  7 +
  8 +class FPM::Deb < FPM::Package
  9 +
  10 + # Assemble the package.
  11 + # params:
  12 + # "root" => "/some/path" # the 'root' of your package directory
  13 + # "paths" => [ "/some/path" ...] # paths to icnlude in this package
  14 + # "output" => "foo.deb" # what to output to.
  15 + #
  16 + # The 'output' file path will have 'VERSION' and 'ARCH' replaced with
  17 + # the appropriate values if if you want the filename generated.
  18 + def assemble(params)
  19 + raise "No package name given. Can't assemble package" if !@name
  20 +
  21 + root = params["root"]
  22 + paths = params["paths"]
  23 + output = params["output"]
  24 + type = "deb"
  25 +
  26 + p self.inspect
  27 +
  28 + # Debian calls x86_64 "amd64"
  29 + @architecture = "amd64" if @architecture == "x86_64"
  30 +
  31 + output.gsub!(/VERSION/, "#{@version}-#{@iteration}")
  32 + output.gsub!(/ARCH/, @architecture)
  33 +
  34 + builddir = "#{Dir.pwd}/build-#{type}-#{File.basename(output)}"
  35 + @garbage << builddir
  36 +
  37 + Dir.mkdir(builddir) if !File.directory?(builddir)
  38 +
  39 + Dir.chdir(root || ".") do
  40 + self.tar("#{builddir}/data.tar", paths)
  41 + # TODO(sissel): Make a helper method.
  42 + system(*["gzip", "-f", "#{builddir}/data.tar"])
  43 +
  44 + # Generate md5sums
  45 + md5sums = self.checksum(paths)
  46 + File.open("#{builddir}/md5sums", "w") { |f| f.puts md5sums.join("\n") }
  47 +
  48 + # Generate 'control' file
  49 + template = File.new("#{File.dirname(__FILE__)}/../../templates/deb.erb").read()
  50 + control = ERB.new(template).result(binding)
  51 + File.open("#{builddir}/control", "w") { |f| f.puts control }
  52 + end
  53 +
  54 + # create control.tar.gz
  55 + Dir.chdir(builddir) do
  56 + # Make the control
  57 + system("tar -zcf control.tar.gz control md5sums")
  58 +
  59 + # create debian-binary
  60 + File.open("debian-binary", "w") { |f| f.puts "2.0" }
  61 +
  62 + # pack up the .deb
  63 + system("ar -qc #{output} debian-binary control.tar.gz data.tar.gz")
  64 + end
  65 + end # def assemble
  66 +
  67 + def checksum(paths)
  68 + md5sums = []
  69 + paths.each do |path|
  70 + md5sums += %x{find #{path} -type f -print0 | xargs -0 md5sum}.split("\n")
  71 + end
  72 + end # def checksum
  73 +end # class FPM::Deb
  74 +
1  lib/fpm/namespace.rb
... ... @@ -0,0 +1 @@
  1 +module FPM; end
65 lib/fpm/package.rb
... ... @@ -0,0 +1,65 @@
  1 +require "fpm/namespace"
  2 +require "socket" # for Socket.gethostname
  3 +
  4 +class FPM::Package
  5 + # The name of this package
  6 + attr_accessor :name
  7 +
  8 + # The version of this package (the upstream version)
  9 + attr_accessor :version
  10 +
  11 + # The iteration of this package.
  12 + # Debian calls this 'release' and is the last '-NUMBER' in the version
  13 + # RedHat has this as 'Release' in the .spec file
  14 + # FreeBSD calls this 'PORTREVISION'
  15 + # If left unpicked, it defaults to 1.
  16 + attr_accessor :iteration
  17 +
  18 + # Who maintains this package? This could be the upstream author
  19 + # or the package maintainer. You pick.
  20 + attr_accessor :maintainer
  21 +
  22 + # URL for this package.
  23 + # Could be the homepage. Could be the download url. You pick.
  24 + attr_accessor :url
  25 +
  26 + # The category of this package.
  27 + # RedHat calls this 'Group'
  28 + # Debian calls this 'Section'
  29 + # FreeBSD would put this in /usr/ports/<category>/...
  30 + attr_accessor :category
  31 +
  32 + # A identifier representing the license. Any string is fine.
  33 + attr_accessor :license
  34 +
  35 + # What architecture is this package for?
  36 + attr_accessor :architecture
  37 +
  38 + # TODO(sissel): Dependencies?
  39 +
  40 + def initialize
  41 + @iteration = 1
  42 + @url = ""
  43 + @category = "default"
  44 + @license = "unknown"
  45 + @maintainer = "<#{ENV["USER"]}@#{Socket.gethostname}>"
  46 + @architecture = nil
  47 +
  48 + # Garbage is stuff you may want to clean up.
  49 + @garbage = []
  50 + end
  51 +
  52 + def tar(output, paths)
  53 + dirs = []
  54 + paths.each do |path|
  55 + while path != "/" and path != "."
  56 + dirs << path if !dirs.include?(path)
  57 + path = File.dirname(path)
  58 + end
  59 + end # paths.each
  60 + dirs = dirs.sort { |a,b| a.length <=> b.length}
  61 + system(*["tar", "--owner=root", "--group=root", "-cf", output, "--no-recursion", *dirs])
  62 + system(*["tar", "--owner=root", "--group=root", "-rf", output, *paths])
  63 + end
  64 +
  65 +end
18 templates/deb.erb
... ... @@ -1,12 +1,12 @@
1   -Package: <%= package %>
2   -Version: <%= version %>-<%= package_iteration %>
3   -Architecture: <%= architecture %>
4   -Maintainer: <%= maintainer %>
  1 +Package: <%= @package %>
  2 +Version: <%= @version %>-<%= @package_iteration %>
  3 +Architecture: <%= @architecture %>
  4 +Maintainer: <%= @maintainer %>
5 5 Installed-Size: 12345
6   -Depends: <%= dependencies.join(", ") %>
7   -Section: <%= category %>
  6 +Depends: <%= @dependencies.join(", ") rescue "" %>
  7 +Section: <%= @category %>
8 8 Priority: extra
9   -Homepage: <%= url %>
10   -Description: <%= summary %>
11   - <%= summary %>
  9 +Homepage: <%= @url %>
  10 +Description: <%= @summary %>
  11 + <%= @summary %>
12 12
2  tools/npm2pkg.rb
@@ -56,7 +56,7 @@
56 56 maintainer = "#{m["name"]} <#{m["email"]}>"
57 57 end
58 58
59   - pkgcmd = [ "ruby", "bin/pkg.rb",
  59 + pkgcmd = [ "fpm",
60 60 "-n", "nodejs-#{package["name"]}",
61 61 "-v", package["version"],
62 62 "-m", maintainer,

0 comments on commit 5b942f2

Please sign in to comment.
Something went wrong with that request. Please try again.