fpm 0.4.32 → 0.4.35
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELIST +16 -0
- data/CONTRIBUTORS +1 -0
- data/lib/fpm/command.rb +23 -50
- data/lib/fpm/package.rb +4 -4
- data/lib/fpm/package/cpan.rb +190 -0
- data/lib/fpm/package/deb.rb +7 -2
- data/lib/fpm/package/npm.rb +89 -27
- data/lib/fpm/package/pyfpm/__init__.pyc +0 -0
- data/lib/fpm/package/pyfpm/get_metadata.pyc +0 -0
- data/lib/fpm/package/rpm.rb +60 -1
- data/lib/fpm/version.rb +1 -1
- data/templates/deb.erb +2 -2
- data/templates/rpm.erb +42 -32
- data/templates/rpm/filesystem_list +14514 -0
- metadata +153 -107
data/CHANGELIST
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
0.4.35 (May 8, 2013)
|
2
|
+
- Fix dependencies listed in the gem.
|
3
|
+
|
4
|
+
0.4.34 (May 7, 2013)
|
5
|
+
- Now supports CPAN - Perl mongers rejoice! For example:
|
6
|
+
'fpm -s cpan -t deb DBI'
|
7
|
+
- deb: fixed some additional complaints by lintian (#420, patch by Pranay
|
8
|
+
Kanwar)
|
9
|
+
- rpm: add flags --rpm-autoreqprov, --rpm-autoreq, and --rpm-autoprov
|
10
|
+
to tell rpm to enable that feature in the rpm spec. (#416, patch by Adam
|
11
|
+
Stephens)
|
12
|
+
|
13
|
+
0.4.33 (April 9, 2013)
|
14
|
+
- Now supports npm, the node package manager. For example:
|
15
|
+
'fpm -s npm -t deb express'
|
16
|
+
|
1
17
|
0.4.32 (April 9, 2013)
|
2
18
|
- COMPATIBILITY WARNING: rpm: The default epoch is now nothing because this
|
3
19
|
aligns more closely with typical rpm packages in the real world. This
|
data/CONTRIBUTORS
CHANGED
@@ -18,6 +18,7 @@ Thomas Meson (github: zllak)
|
|
18
18
|
Oliver Hookins (github: ohookins)
|
19
19
|
llasram
|
20
20
|
sbuss
|
21
|
+
Brett Gailey (github: dnbert)
|
21
22
|
|
22
23
|
If you have contributed (bug reports, feature requests, help in IRC, blog
|
23
24
|
posts, code, etc) and aren't listed here, please let me know if you wish to be
|
data/lib/fpm/command.rb
CHANGED
@@ -77,52 +77,34 @@ class FPM::Command < Clamp::Command
|
|
77
77
|
option ["-d", "--depends"], "DEPENDENCY",
|
78
78
|
"A dependency. This flag can be specified multiple times. Value is " \
|
79
79
|
"usually in the form of: -d 'name' or -d 'name > version'",
|
80
|
-
:
|
81
|
-
# Clamp doesn't support multivalue flags (ie; specifying -d multiple times)
|
82
|
-
# so we can hack around it with this trickery.
|
83
|
-
@dependencies ||= []
|
84
|
-
@dependencies << val
|
85
|
-
end # -d / --depends
|
80
|
+
:multivalued => true, :attribute_name => :dependencies
|
86
81
|
|
87
82
|
option "--no-depends", :flag, "Do not list any dependencies in this package",
|
88
83
|
:default => false
|
89
84
|
|
90
|
-
option "--no-auto-depends", :flag, "Do not list any dependencies in this
|
91
|
-
:default => false
|
85
|
+
option "--no-auto-depends", :flag, "Do not list any dependencies in this" \
|
86
|
+
"package automatically", :default => false
|
92
87
|
|
93
88
|
option "--provides", "PROVIDES",
|
94
89
|
"What this package provides (usually a name). This flag can be "\
|
95
|
-
"specified multiple times."
|
96
|
-
|
97
|
-
@provides << val
|
98
|
-
end # --provides
|
90
|
+
"specified multiple times.", :multivalued => true,
|
91
|
+
:attribute_name => :provides
|
99
92
|
option "--conflicts", "CONFLICTS",
|
100
93
|
"Other packages/versions this package conflicts with. This flag can " \
|
101
|
-
"specified multiple times."
|
102
|
-
|
103
|
-
@conflicts << val
|
104
|
-
end # --conflicts
|
94
|
+
"specified multiple times.", :multivalued => true,
|
95
|
+
:attribute_name => :conflicts
|
105
96
|
option "--replaces", "REPLACES",
|
106
97
|
"Other packages/versions this package replaces. This flag can be "\
|
107
|
-
"specified multiple times."
|
108
|
-
|
109
|
-
|
110
|
-
end # --replaces
|
98
|
+
"specified multiple times.", :multivalued => true,
|
99
|
+
:attribute_name => :replaces
|
100
|
+
|
111
101
|
option "--config-files", "CONFIG_FILES",
|
112
102
|
"Mark a file in the package as being a config file. This uses 'conffiles'" \
|
113
103
|
" in debs and %config in rpm. If you have multiple files to mark as " \
|
114
|
-
"configuration files, specify this flag multiple times."
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
@config_files << val
|
119
|
-
end # --config-files
|
120
|
-
option "--directories", "DIRECTORIES",
|
121
|
-
"Mark a directory as being owned by the package" \
|
122
|
-
do |val|
|
123
|
-
@directories ||= []
|
124
|
-
@directories << val
|
125
|
-
end # directories
|
104
|
+
"configuration files, specify this flag multiple times.",
|
105
|
+
:multivalued => true, :attribute_name => :config_files
|
106
|
+
option "--directories", "DIRECTORIES", "Mark a directory as being owned " \
|
107
|
+
"by the package", :multivalued => true, :attribute_name => :directories
|
126
108
|
option ["-a", "--architecture"], "ARCHITECTURE",
|
127
109
|
"The architecture name. Usually matches 'uname -m'. For automatic values," \
|
128
110
|
" you can use '-a all' or '-a native'. These two strings will be " \
|
@@ -134,12 +116,14 @@ class FPM::Command < Clamp::Command
|
|
134
116
|
"a name suffix to append to package and dependencies."
|
135
117
|
option ["-e", "--edit"], :flag,
|
136
118
|
"Edit the package spec before building.", :default => false
|
119
|
+
|
120
|
+
excludes = []
|
137
121
|
option ["-x", "--exclude"], "EXCLUDE_PATTERN",
|
138
122
|
"Exclude paths matching pattern (shell wildcard globs valid here). " \
|
139
123
|
"If you have multiple file patterns to exclude, specify this flag " \
|
140
124
|
"multiple times.", :attribute_name => :excludes do |val|
|
141
|
-
|
142
|
-
|
125
|
+
excludes << val
|
126
|
+
next excludes
|
143
127
|
end # -x / --exclude
|
144
128
|
option "--description", "DESCRIPTION", "Add a description for this package." \
|
145
129
|
" You can include '\n' sequences to indicate newline breaks.",
|
@@ -199,10 +183,10 @@ class FPM::Command < Clamp::Command
|
|
199
183
|
|
200
184
|
option "--template-value", "KEY=VALUE",
|
201
185
|
"Make 'key' available in script templates, so <%= key %> given will be " \
|
202
|
-
"the provided value. Implies --template-scripts"
|
186
|
+
"the provided value. Implies --template-scripts",
|
187
|
+
:multivalued => true do |kv|
|
203
188
|
@template_scripts = true
|
204
|
-
|
205
|
-
@template_values << kv.split("=", 2)
|
189
|
+
next kv.split("=", 2)
|
206
190
|
end
|
207
191
|
|
208
192
|
option "--workdir", "WORKDIR",
|
@@ -220,16 +204,6 @@ class FPM::Command < Clamp::Command
|
|
220
204
|
klass.apply_options(self)
|
221
205
|
end
|
222
206
|
|
223
|
-
# TODO(sissel): expose 'option' and 'parameter' junk to FPM::Package and subclasses.
|
224
|
-
# Apply those things to this command.
|
225
|
-
#
|
226
|
-
# Add extra flags from plugins
|
227
|
-
#FPM::Package::Gem.flags(FPM::Flags.new(opts, "gem", "gem only"), @settings)
|
228
|
-
#FPM::Package::Python.flags(FPM::Flags.new(opts, "python", "python only"),
|
229
|
-
#@settings)
|
230
|
-
#FPM::Package::Deb.flags(FPM::Flags.new(opts, "deb", "deb only"), @settings)
|
231
|
-
#FPM::Package::Rpm.flags(FPM::Flags.new(opts, "rpm", "rpm only"), @settings)
|
232
|
-
|
233
207
|
# A new FPM::Command
|
234
208
|
def initialize(*args)
|
235
209
|
super(*args)
|
@@ -239,7 +213,6 @@ class FPM::Command < Clamp::Command
|
|
239
213
|
@dependencies = []
|
240
214
|
@config_files = []
|
241
215
|
@directories = []
|
242
|
-
@excludes = []
|
243
216
|
end # def initialize
|
244
217
|
|
245
218
|
# Execute this command. See Clamp::Command#execute and Clamp's documentation
|
@@ -406,8 +379,8 @@ class FPM::Command < Clamp::Command
|
|
406
379
|
output = input.convert(output_class)
|
407
380
|
|
408
381
|
# Provide any template values as methods on the package.
|
409
|
-
if
|
410
|
-
|
382
|
+
if template_scripts?
|
383
|
+
template_value_list.each do |key, value|
|
411
384
|
(class << output; self; end).send(:define_method, key) { value }
|
412
385
|
end
|
413
386
|
end
|
data/lib/fpm/package.rb
CHANGED
@@ -93,9 +93,6 @@ class FPM::Package
|
|
93
93
|
# (Not all packages support this)
|
94
94
|
attr_accessor :replaces
|
95
95
|
|
96
|
-
# Array of glob patterns to exclude from this package
|
97
|
-
attr_accessor :excludes
|
98
|
-
|
99
96
|
# a summary or description of the package
|
100
97
|
attr_accessor :description
|
101
98
|
|
@@ -315,8 +312,11 @@ class FPM::Package
|
|
315
312
|
.collect { |path| path[staging_path.length + 1.. -1] }
|
316
313
|
end # def files
|
317
314
|
|
315
|
+
def template_dir
|
316
|
+
File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "templates"))
|
317
|
+
end
|
318
|
+
|
318
319
|
def template(path)
|
319
|
-
template_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "templates"))
|
320
320
|
template_path = File.join(template_dir, path)
|
321
321
|
template_code = File.read(template_path)
|
322
322
|
@logger.info("Reading template", :path => template_path)
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require "fpm/namespace"
|
2
|
+
require "fpm/package"
|
3
|
+
require "fpm/util"
|
4
|
+
require "fileutils"
|
5
|
+
require "find"
|
6
|
+
|
7
|
+
class FPM::Package::CPAN < FPM::Package
|
8
|
+
# Flags '--foo' will be accessable as attributes[:npm_foo]
|
9
|
+
option "--perl-bin", "PERL_EXECUTABLE",
|
10
|
+
"The path to the perl executable you wish to run.", :default => "perl"
|
11
|
+
option "--cpanm-bin", "CPANM_EXECUTABLE",
|
12
|
+
"The path to the cpanm executable you wish to run.", :default => "cpanm"
|
13
|
+
option "--package-name-prefix", "NAME_PREFIX", "Name to prefix the package " \
|
14
|
+
"name with.", :default => "perl"
|
15
|
+
option "--test", :flag, "Run the tests before packaging?", :default => true
|
16
|
+
|
17
|
+
private
|
18
|
+
def input(package)
|
19
|
+
require "ftw" # for http access
|
20
|
+
require "json"
|
21
|
+
|
22
|
+
agent = FTW::Agent.new
|
23
|
+
result = search(package, agent)
|
24
|
+
tarball = download(result, agent)
|
25
|
+
moduledir = unpack(tarball)
|
26
|
+
|
27
|
+
# Read package metadata (name, version, etc)
|
28
|
+
if File.exists?(File.join(moduledir, "META.json"))
|
29
|
+
metadata = JSON.parse(File.read(File.join(moduledir, ("META.json"))))
|
30
|
+
elsif File.exists?(File.join(moduledir, ("META.yml")))
|
31
|
+
require "yaml"
|
32
|
+
metadata = YAML.load_file(File.join(moduledir, ("META.yml")))
|
33
|
+
else
|
34
|
+
raise FPM::InvalidPackageConfiguration,
|
35
|
+
"Could not find package metadata. Checked for META.json and META.yml"
|
36
|
+
end
|
37
|
+
self.version = metadata["version"]
|
38
|
+
self.description = metadata["abstract"]
|
39
|
+
|
40
|
+
self.license = case metadata["license"]
|
41
|
+
when Array; metadata["license"].first
|
42
|
+
else; metadata["license"]
|
43
|
+
end
|
44
|
+
|
45
|
+
if metadata.include?("distribution")
|
46
|
+
@logger.info("Setting package name from 'distribution'",
|
47
|
+
:distribution => metadata["distribution"])
|
48
|
+
self.name = fix_name(metadata["distribution"])
|
49
|
+
else
|
50
|
+
@logger.info("Setting package name from 'name'",
|
51
|
+
:name => metadata["name"])
|
52
|
+
self.name = fix_name(metadata["name"])
|
53
|
+
end
|
54
|
+
|
55
|
+
# Not all things have 'author' listed.
|
56
|
+
self.vendor = metadata["author"].join(", ") if metadata.include?("author")
|
57
|
+
self.url = metadata["resources"]["homepage"] rescue "unknown"
|
58
|
+
|
59
|
+
# TODO(sissel): figure out if this perl module compiles anything
|
60
|
+
# and set the architecture appropriately.
|
61
|
+
self.architecture = "all"
|
62
|
+
|
63
|
+
# Install any build/configure dependencies with cpanm.
|
64
|
+
# We'll install to a temporary directory.
|
65
|
+
@logger.info("Installing any build or configure dependencies")
|
66
|
+
safesystem(attributes[:cpan_cpanm_bin], "-L", build_path("cpan"), moduledir)
|
67
|
+
|
68
|
+
if !attributes[:no_auto_depends?]
|
69
|
+
if metadata.include?("requires")
|
70
|
+
metadata["requires"].each do |dep_name, version|
|
71
|
+
# Special case for representing perl core as a version.
|
72
|
+
if dep_name == "perl"
|
73
|
+
self.dependencies << "#{dep_name} >= #{version}"
|
74
|
+
next
|
75
|
+
end
|
76
|
+
dep = search(dep_name, agent)
|
77
|
+
|
78
|
+
if dep.include?("distribution")
|
79
|
+
name = fix_name(dep["distribution"])
|
80
|
+
else
|
81
|
+
name = fix_name(dep_name)
|
82
|
+
end
|
83
|
+
|
84
|
+
if version.to_s == "0"
|
85
|
+
# Assume 'Foo = 0' means any version?
|
86
|
+
self.dependencies << "#{name}"
|
87
|
+
else
|
88
|
+
self.dependencies << "#{name} = #{version}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end #no_auto_depends
|
93
|
+
|
94
|
+
::Dir.chdir(moduledir) do
|
95
|
+
# TODO(sissel): install build and config dependencies to resolve
|
96
|
+
# build/configure requirements.
|
97
|
+
# META.yml calls it 'configure_requires' and 'build_requires'
|
98
|
+
# META.json calls it prereqs/build and prereqs/configure
|
99
|
+
|
100
|
+
prefix = attributes[:prefix] || "/usr/local"
|
101
|
+
# TODO(sissel): Set default INSTALL path?
|
102
|
+
# perl -e 'use Config; print "$Config{sitelib}"'
|
103
|
+
safesystem(attributes[:cpan_perl_bin],
|
104
|
+
"-Mlocal::lib=#{build_path("cpan")}",
|
105
|
+
"Makefile.PL",
|
106
|
+
"PREFIX=#{prefix}",
|
107
|
+
# Have to specify INSTALL_BASE as empty otherwise
|
108
|
+
# Makefile.PL lies and claims we've set both PREFIX and
|
109
|
+
# INSTALL_BASE.
|
110
|
+
"INSTALL_BASE="
|
111
|
+
)
|
112
|
+
|
113
|
+
make = [ "make" ]
|
114
|
+
|
115
|
+
safesystem(*make)
|
116
|
+
safesystem(*(make + ["test"])) if attributes[:cpan_test?]
|
117
|
+
safesystem(*(make + ["DESTDIR=#{staging_path}", "install"]))
|
118
|
+
end
|
119
|
+
|
120
|
+
# TODO(sissel): figure out if this perl module compiles anything
|
121
|
+
# and set the architecture appropriately.
|
122
|
+
self.architecture = "all"
|
123
|
+
|
124
|
+
# Find any shared objects in the staging directory to set architecture as
|
125
|
+
# native if found; otherwise keep the 'all' default.
|
126
|
+
Find.find(staging_path) do |path|
|
127
|
+
if path =~ /\.so$/
|
128
|
+
@logger.info("Found shared library, setting architecture=native",
|
129
|
+
:path => path)
|
130
|
+
self.architecture = "native"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def unpack(tarball)
|
136
|
+
directory = build_path("module")
|
137
|
+
::Dir.mkdir(directory)
|
138
|
+
args = [ "-C", directory, "-zxf", tarball,
|
139
|
+
"--strip-components", "1" ]
|
140
|
+
safesystem("tar", *args)
|
141
|
+
return directory
|
142
|
+
end
|
143
|
+
|
144
|
+
def download(metadata, agent)
|
145
|
+
distribution = metadata["distribution"]
|
146
|
+
author = metadata["author"]
|
147
|
+
@logger.info("Downloading perl module",
|
148
|
+
:distribution => distribution,
|
149
|
+
:version => version)
|
150
|
+
|
151
|
+
# default to latest versionunless we specify one
|
152
|
+
version = metadata["version"] if version.nil?
|
153
|
+
|
154
|
+
tarball = "#{distribution}-#{version}.tar.gz"
|
155
|
+
url = "http://search.cpan.org/CPAN/authors/id/#{author[0,1]}/#{author[0,2]}/#{author}/#{tarball}"
|
156
|
+
response = agent.get!(url)
|
157
|
+
if response.error?
|
158
|
+
@logger.error("Download failed", :error => response.status_line,
|
159
|
+
:url => url)
|
160
|
+
raise FPM::InvalidPackageConfiguration, "metacpan query failed"
|
161
|
+
end
|
162
|
+
|
163
|
+
File.open(build_path(tarball), "w") do |fd|
|
164
|
+
response.read_body { |c| fd.write(c) }
|
165
|
+
end
|
166
|
+
return build_path(tarball)
|
167
|
+
end # def download
|
168
|
+
|
169
|
+
def search(package, agent)
|
170
|
+
@logger.info("Asking metacpan about a module", :module => package)
|
171
|
+
metacpan_url = "http://api.metacpan.org/v0/module/" + package
|
172
|
+
response = agent.get!(metacpan_url)
|
173
|
+
if response.error?
|
174
|
+
@logger.error("metacpan query failed.", :error => response.status_line,
|
175
|
+
:module => package, :url => metacpan_url)
|
176
|
+
raise FPM::InvalidPackageConfiguration, "metacpan query failed"
|
177
|
+
end
|
178
|
+
|
179
|
+
data = ""
|
180
|
+
response.read_body { |c| data << c }
|
181
|
+
metadata = JSON.parse(data)
|
182
|
+
return metadata
|
183
|
+
end # def metadata
|
184
|
+
|
185
|
+
def fix_name(name)
|
186
|
+
return [attributes[:cpan_package_name_prefix], name].join("-").gsub("::", "-")
|
187
|
+
end # def fix_name
|
188
|
+
|
189
|
+
public(:input)
|
190
|
+
end # class FPM::Package::NPM
|
data/lib/fpm/package/deb.rb
CHANGED
@@ -126,9 +126,14 @@ class FPM::Package::Deb < FPM::Package
|
|
126
126
|
@architecture = %x{uname -m}.chomp
|
127
127
|
end
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
|
+
case @architecture
|
131
|
+
when "x86_64"
|
130
132
|
# Debian calls x86_64 "amd64"
|
131
133
|
@architecture = "amd64"
|
134
|
+
when "noarch"
|
135
|
+
# Debian calls noarch "all"
|
136
|
+
@architecture = "all"
|
132
137
|
end
|
133
138
|
return @architecture
|
134
139
|
end # def architecture
|
@@ -432,7 +437,7 @@ class FPM::Package::Deb < FPM::Package
|
|
432
437
|
# Make the control.tar.gz
|
433
438
|
with(build_path("control.tar.gz")) do |controltar|
|
434
439
|
@logger.info("Creating", :path => controltar, :from => control_path)
|
435
|
-
safesystem(tar_cmd, "--
|
440
|
+
safesystem(tar_cmd, "--owner=root", "--group=root", "-zcf",
|
436
441
|
controltar, "-C", control_path, ".")
|
437
442
|
end
|
438
443
|
|
data/lib/fpm/package/npm.rb
CHANGED
@@ -4,33 +4,95 @@ require "fpm/util"
|
|
4
4
|
require "fileutils"
|
5
5
|
|
6
6
|
class FPM::Package::NPM < FPM::Package
|
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
|
-
|
7
|
+
# Flags '--foo' will be accessable as attributes[:npm_foo]
|
8
|
+
option "--bin", "NPM_EXECUTABLE",
|
9
|
+
"The path to the npm executable you wish to run.", :default => "npm"
|
10
|
+
|
11
|
+
option "--package-name-prefix", "PREFIX", "Name to prefix the package " \
|
12
|
+
"name with.", :default => "node"
|
13
|
+
|
14
|
+
private
|
15
|
+
def input(package)
|
16
|
+
# Notes:
|
17
|
+
# * npm respects PREFIX
|
18
|
+
settings = {
|
19
|
+
"cache" => build_path("npm_cache"),
|
20
|
+
"loglevel" => "warn",
|
21
|
+
"global" => "true"
|
22
|
+
}
|
23
|
+
|
24
|
+
if attributes.include?(:prefix) && !attributes[:prefix].nil?
|
25
|
+
settings["prefix"] = staging_path(attributes[:prefix])
|
26
|
+
else
|
27
|
+
@logger.info("Setting default npm install prefix",
|
28
|
+
:prefix => "/usr/local")
|
29
|
+
settings["prefix"] = staging_path("/usr/local")
|
30
|
+
end
|
31
|
+
|
32
|
+
FileUtils.mkdir_p(settings["prefix"])
|
33
|
+
|
34
|
+
npm_flags = []
|
35
|
+
settings.each do |key, value|
|
36
|
+
# npm lets you specify settings in a .npmrc but the same key=value settings
|
37
|
+
# are valid as '--key value' command arguments to npm. Woo!
|
38
|
+
@logger.debug("Configuring npm", key => value)
|
39
|
+
npm_flags += [ "--#{key}", value ]
|
40
|
+
end
|
41
|
+
|
42
|
+
install_args = [
|
43
|
+
attributes[:npm_bin],
|
44
|
+
"install",
|
45
|
+
# use 'package' or 'package@version'
|
46
|
+
(version ? "#{package}@#{version}" : package)
|
47
|
+
]
|
48
|
+
|
49
|
+
# The only way to get npm to respect the 'prefix' setting appears to
|
50
|
+
# be to set the --global flag.
|
51
|
+
#install_args << "--global"
|
52
|
+
install_args += npm_flags
|
53
|
+
|
54
|
+
safesystem(*install_args)
|
55
|
+
|
56
|
+
# Query details about our now-installed package.
|
57
|
+
# We do this by using 'npm ls' with json + long enabled to query details
|
58
|
+
# about the installed package.
|
59
|
+
npm_ls_cmd = [attributes[:npm_bin], "ls", "--json", "--long", package] + npm_flags
|
60
|
+
npm_ls_fd = IO.popen(npm_ls_cmd)
|
61
|
+
npm_ls_out = npm_ls_fd.read()
|
62
|
+
pid, status = Process.waitpid2(npm_ls_fd.pid)
|
63
|
+
if !status.success?
|
64
|
+
raise FPM::Util::ProcessFailed.new("#{npm_ls_cmd.first} failed (exit " \
|
65
|
+
"code #{status.exitstatus}). " \
|
66
|
+
"Full command was: #{npm_ls_cmd.inspect}")
|
67
|
+
end
|
68
|
+
npm_ls = JSON.parse(npm_ls_out)
|
69
|
+
name, info = npm_ls["dependencies"].first
|
70
|
+
|
71
|
+
self.name = [attributes[:npm_package_name_prefix], name].join("-")
|
72
|
+
self.version = info["version"]
|
73
|
+
|
74
|
+
if info.include?("repository")
|
75
|
+
self.url = info["repository"]["url"]
|
76
|
+
else
|
77
|
+
self.url = "https://npmjs.org/package/#{self.name}"
|
78
|
+
end
|
79
|
+
|
80
|
+
self.description = info["description"]
|
81
|
+
self.vendor = sprintf("%s <%s>", info["author"]["name"],
|
82
|
+
info["author"]["email"])
|
83
|
+
|
84
|
+
# npm installs dependencies in the module itself, so if you do
|
85
|
+
# 'npm install express' it installs dependencies (like 'connect')
|
86
|
+
# to: node_modules/express/node_modules/connect/...
|
87
|
+
#
|
88
|
+
# To that end, I don't think we necessarily need to include
|
89
|
+
# any automatic dependency information since every 'npm install'
|
90
|
+
# is fully self-contained. That's why you don't see any bother, yet,
|
91
|
+
# to include the package's dependencies in here.
|
92
|
+
#
|
93
|
+
# It's possible someone will want to decouple that in the future,
|
94
|
+
# but I will wait for that feature request.
|
34
95
|
end
|
35
96
|
|
97
|
+
public(:input)
|
36
98
|
end # class FPM::Package::NPM
|