fpm 0.4.32 → 0.4.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|