license_finder 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/CONTRIBUTING.md +17 -3
- data/Dockerfile +12 -15
- data/README.md +3 -1
- data/Rakefile +7 -0
- data/ci/pipelines/pipeline.yml.erb +2 -2
- data/features/features/cli/cli_spec.rb +4 -3
- data/features/support/testing_dsl.rb +9 -2
- data/lib/license_finder/cli/base.rb +1 -1
- data/lib/license_finder/cli/main.rb +7 -0
- data/lib/license_finder/configuration.rb +4 -0
- data/lib/license_finder/core.rb +2 -2
- data/lib/license_finder/decision_applier.rb +8 -4
- data/lib/license_finder/package_managers/cocoa_pods.rb +6 -10
- data/lib/license_finder/package_managers/go_vendor.rb +2 -0
- data/lib/license_finder/package_managers/go_workspace.rb +2 -0
- data/lib/license_finder/package_managers/maven.rb +2 -1
- data/lib/license_finder/package_managers/npm.rb +66 -58
- data/lib/license_finder/package_managers/npm_package.rb +0 -14
- data/lib/license_finder/package_managers/nuget.rb +6 -1
- data/lib/license_finder/reports/csv_report.rb +6 -2
- data/lib/license_finder/version.rb +1 -1
- data/license_finder.gemspec +1 -0
- data/spec/fixtures/npm-circular-licenses/npm-list.json +7597 -0
- data/spec/fixtures/npm-circular-licenses/package.json +23 -0
- data/spec/lib/license_finder/cli/main_spec.rb +31 -7
- data/spec/lib/license_finder/core_spec.rb +1 -0
- data/spec/lib/license_finder/decision_applier_spec.rb +8 -0
- data/spec/lib/license_finder/package_managers/go_dep_spec.rb +17 -16
- data/spec/lib/license_finder/package_managers/npm_spec.rb +37 -3
- data/spec/lib/license_finder/package_managers/nuget_spec.rb +12 -1
- metadata +21 -5
- data/spec/lib/license_finder/package_managers/npm_package_spec.rb +0 -56
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 499f2da3bda92418516368e51583453fc1c5225f
|
4
|
+
data.tar.gz: a8b35a1beb522d75a1cb573e68be86fe7bd0f921
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1986e42151dfa364cfe7e10500b5fda295f957ae1fd62f1605067aac46bdfca0c8b596d9ded82b3192ddfecea804a312cb0cf7d6314e6713ea8f03a2ddf6bdd
|
7
|
+
data.tar.gz: fb51163eeb86d7e19fd77de0f26f5930048c8a7a8441a50db4b852f90539ce0402109acb375c87324054ed1be99a51d77a71ca108ba8d019e13fb8f189014f47
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# Not Yet Released:
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
* Add --maven-options to allow options for maven scans (#305, thanks @jgielstra!)
|
6
|
+
|
7
|
+
Bugfixes:
|
8
|
+
|
9
|
+
* Restore the original GOPATH after modifying it (#287, thanks @sschuberth!)
|
10
|
+
* LF doesn't recognize .NET projects using 'packages' directory (#290, #292, thanks @bspeck!)
|
11
|
+
* Use glob for finding acknowledgements path for CocoaPods (#177, #288, thanks @aditya87!)
|
12
|
+
* Fix some failing tests on Windows (#294, thanks @sschuberth!)
|
13
|
+
* Add warning message if no dependencies are recognized (#293, thanks @bspeck!)
|
14
|
+
* Switch to YAJL for parsing the json output from npm using a tmp file rather than an in-memory string (#301, #304)
|
15
|
+
|
1
16
|
# 3.0.0 / 2016-03-02
|
2
17
|
|
3
18
|
Features:
|
data/CONTRIBUTING.md
CHANGED
@@ -8,6 +8,18 @@
|
|
8
8
|
* Rebase on top of master.
|
9
9
|
* Send a pull request.
|
10
10
|
|
11
|
+
## Running Tests
|
12
|
+
|
13
|
+
You can use the [LicenseFinder docker image](https://hub.docker.com/r/licensefinder/license_finder/) to run the tests.
|
14
|
+
|
15
|
+
```
|
16
|
+
$ docker run -it licensefinder/license_finder /bin/bash --login
|
17
|
+
|
18
|
+
# inside the container...
|
19
|
+
|
20
|
+
$ cd /LicenseFinder
|
21
|
+
$ rake
|
22
|
+
```
|
11
23
|
|
12
24
|
## Adding Package Managers
|
13
25
|
|
@@ -44,7 +56,8 @@ If you come up with something useful, consider posting it to the Google Group
|
|
44
56
|
|
45
57
|
|
46
58
|
## Development Dependencies
|
47
|
-
|
59
|
+
|
60
|
+
To successfully run the test suite, you will need the following installed:
|
48
61
|
- NPM (requires Node)
|
49
62
|
- Bower (requires Node and NPM)
|
50
63
|
- Maven (requires Java)
|
@@ -55,8 +68,9 @@ To successfully run the test suite, you will need the following installed:
|
|
55
68
|
- CocoaPods (requires ruby)
|
56
69
|
- Bundler (requires ruby)
|
57
70
|
|
58
|
-
|
59
|
-
|
71
|
+
The [LicenseFinder docker image](https://hub.docker.com/r/licensefinder/license_finder/) already contains these dependencies.
|
72
|
+
|
73
|
+
If you run `rake check_dependencies`, you'll see exactly which package managers you're missing.
|
60
74
|
|
61
75
|
### Python
|
62
76
|
|
data/Dockerfile
CHANGED
@@ -1,32 +1,21 @@
|
|
1
1
|
FROM ubuntu:trusty
|
2
|
-
RUN apt-get update && apt-get install -y curl git-core
|
3
|
-
|
4
|
-
#install rvm
|
5
|
-
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 && \
|
6
|
-
curl -sSL https://get.rvm.io | bash -s stable --ruby
|
7
|
-
ENV PATH=/usr/local/rvm/bin:$PATH
|
8
|
-
|
9
|
-
# install build-essential wget unzip
|
10
|
-
RUN apt-get install -y build-essential wget unzip
|
2
|
+
RUN apt-get update && apt-get install -y curl git-core wget unzip
|
11
3
|
|
12
4
|
# nodejs seems to be required for the one of the gems
|
13
|
-
RUN curl -sL https://deb.nodesource.com/
|
5
|
+
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && \
|
14
6
|
apt-get -y install nodejs
|
15
7
|
|
16
8
|
# install bower
|
17
9
|
RUN npm install -g bower && \
|
18
10
|
echo '{ "allow_root": true }' > /root/.bowerrc
|
19
11
|
|
20
|
-
# install bundler
|
21
|
-
RUN bash -lc "rvm install 2.3.3 && rvm use 2.3.3 && gem install bundler"
|
22
|
-
|
23
12
|
#install java 8
|
24
13
|
#http://askubuntu.com/questions/521145/how-to-install-oracle-java-on-ubuntu-14-04
|
25
14
|
RUN cd /tmp && \
|
26
|
-
wget --quiet --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/
|
15
|
+
wget --quiet --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.tar.gz -O jdk-8.tgz && \
|
27
16
|
tar xf /tmp/jdk-8.tgz && \
|
28
17
|
mkdir -p /usr/lib/jvm && \
|
29
|
-
mv jdk1.8.
|
18
|
+
mv jdk1.8.0_131 /usr/lib/jvm/oracle_jdk8 && \
|
30
19
|
rm /tmp/jdk-8.tgz
|
31
20
|
|
32
21
|
ENV J2SDKDIR=/usr/lib/jvm/oracle_jdk8
|
@@ -76,6 +65,14 @@ ENV LANG=en_US.UTF-8
|
|
76
65
|
ENV LANGUAGE=en_US:en
|
77
66
|
ENV LC_ALL=en_US.UTF-8
|
78
67
|
|
68
|
+
#install rvm
|
69
|
+
RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 && \
|
70
|
+
curl -sSL https://raw.githubusercontent.com/wayneeseguin/rvm/stable/binscripts/rvm-installer | sudo bash -s stable --ruby=2.4.1
|
71
|
+
ENV PATH=/usr/local/rvm/bin:$PATH
|
72
|
+
|
73
|
+
# install bundler
|
74
|
+
RUN bash -lc "rvm install 2.4.1 --default && gem install bundler"
|
75
|
+
|
79
76
|
# install license_finder
|
80
77
|
RUN bash -lc "git clone https://github.com/pivotal/LicenseFinder /LicenseFinder && cd /LicenseFinder && bundle install -j4 && rake install"
|
81
78
|
|
data/README.md
CHANGED
@@ -6,7 +6,7 @@ Build status
|
|
6
6
|
* Ruby 2.1.5 [![Ruby 2.1.5 build status](https://osl.ci.cf-app.com/api/v1/teams/main/pipelines/LicenseFinder/jobs/ruby-2.1.5/badge)](https://osl.ci.cf-app.com/teams/main/pipelines/LicenseFinder)
|
7
7
|
* Ruby 2.2.0 [![Ruby 2.2.0 build status](https://osl.ci.cf-app.com/api/v1/teams/main/pipelines/LicenseFinder/jobs/ruby-2.2.0/badge)](https://osl.ci.cf-app.com/teams/main/pipelines/LicenseFinder)
|
8
8
|
* Ruby 2.3.0 [![Ruby 2.3.0 build status](https://osl.ci.cf-app.com/api/v1/teams/main/pipelines/LicenseFinder/jobs/ruby-2.3.0/badge)](https://osl.ci.cf-app.com/teams/main/pipelines/LicenseFinder)
|
9
|
-
* Ruby 2.4.
|
9
|
+
* Ruby 2.4.1 [![Ruby 2.4.1 build status](https://osl.ci.cf-app.com/api/v1/teams/main/pipelines/LicenseFinder/jobs/ruby-2.4.1/badge)](https://osl.ci.cf-app.com/teams/main/pipelines/LicenseFinder)
|
10
10
|
* JRuby 9.0.4.0 [![JRuby 9.0.4.0 build status](https://osl.ci.cf-app.com/api/v1/teams/main/pipelines/LicenseFinder/jobs/ruby-jruby-9.0.4.0/badge)](https://osl.ci.cf-app.com/teams/main/pipelines/LicenseFinder)
|
11
11
|
|
12
12
|
|
@@ -17,6 +17,8 @@ report.
|
|
17
17
|
|
18
18
|
* code: https://github.com/pivotal/LicenseFinder
|
19
19
|
* ci: https://osl.ci.cf-app.com/teams/main/pipelines/LicenseFinder
|
20
|
+
* docker: [licensefinder/license_finder](https://hub.docker.com/r/licensefinder/license_finder/)
|
21
|
+
* the docker image contains all the package managers needed to run `license_finder`
|
20
22
|
* support:
|
21
23
|
* license-finder@googlegroups.com
|
22
24
|
* https://groups.google.com/forum/#!forum/license-finder
|
data/Rakefile
CHANGED
@@ -13,6 +13,13 @@ task :spec do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
desc "Only run cocoapods specs"
|
17
|
+
RSpec::Core::RakeTask.new("spec:cocoapods") do |t|
|
18
|
+
t.fail_on_error = true
|
19
|
+
t.pattern = "./spec/lib/license_finder/package_managers/cocoa_pods_*spec.rb"
|
20
|
+
t.rspec_opts = %w[--color]
|
21
|
+
end
|
22
|
+
|
16
23
|
desc "Run all specs in features/"
|
17
24
|
task :features do
|
18
25
|
RSpec::Core::RakeTask.new(:features) do |t|
|
@@ -35,7 +35,7 @@ resources:
|
|
35
35
|
<% end %>
|
36
36
|
|
37
37
|
jobs:
|
38
|
-
<% ['2.4.
|
38
|
+
<% ['2.4.1', '2.3.0', '2.2.0', '2.1.5', 'jruby-9.0.4.0'].each do |ruby_version| %>
|
39
39
|
- name: ruby-<%= ruby_version %>
|
40
40
|
public: true
|
41
41
|
plan:
|
@@ -55,7 +55,7 @@ jobs:
|
|
55
55
|
<% end %>
|
56
56
|
<% end %>
|
57
57
|
|
58
|
-
<% ['2.4.
|
58
|
+
<% ['2.4.1', '2.3.0', '2.2.0', '2.1.5', 'jruby-9.0.4.0'].each do |ruby_version| %>
|
59
59
|
- name: PR-ruby-<%= ruby_version %>
|
60
60
|
public: true
|
61
61
|
plan:
|
@@ -36,14 +36,15 @@ describe "License Finder command line executable" do
|
|
36
36
|
|
37
37
|
developer.run_license_finder
|
38
38
|
expect(developer).to be_receiving_exit_code(0)
|
39
|
-
expect(developer).to be_seeing '
|
39
|
+
expect(developer).to be_seeing 'No dependencies recognized!'
|
40
40
|
end
|
41
41
|
|
42
42
|
specify "displays an error if project_path does not exist" do
|
43
43
|
developer.create_empty_project
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
path = '/path/that/does/not/exist'
|
46
|
+
developer.execute_command("license_finder report --project-path=#{path}")
|
47
|
+
expect(developer).to be_seeing("Project path '#{File.absolute_path(path)}' does not exist!")
|
47
48
|
expect(developer).to be_receiving_exit_code(1)
|
48
49
|
end
|
49
50
|
end
|
@@ -181,7 +181,10 @@ module LicenseFinder
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def install
|
184
|
-
|
184
|
+
orig_gopath = ENV['GOPATH']
|
185
|
+
ENV['GOPATH'] = "#{project_dir}/gopath"
|
186
|
+
shell_out("godep restore")
|
187
|
+
ENV['GOPATH'] = orig_gopath
|
185
188
|
end
|
186
189
|
|
187
190
|
def shell_out(command)
|
@@ -348,7 +351,11 @@ module LicenseFinder
|
|
348
351
|
end
|
349
352
|
|
350
353
|
def install_fixture(fixture_name)
|
351
|
-
|
354
|
+
if Platform.windows?
|
355
|
+
FileUtils.cp(Paths.fixtures.join(fixture_name), join(fixture_name))
|
356
|
+
else
|
357
|
+
join(fixture_name).make_symlink Paths.fixtures.join(fixture_name)
|
358
|
+
end
|
352
359
|
end
|
353
360
|
|
354
361
|
def make
|
@@ -24,6 +24,7 @@ module LicenseFinder
|
|
24
24
|
class_option :gradle_include_groups, desc: "Whether dependency name should include group id. Only meaningful if used with a Java/gradle project. Defaults to false."
|
25
25
|
class_option :gradle_command, desc: "Command to use when fetching gradle packages. Only meaningful if used with a Java/gradle project. Defaults to 'gradlew' / 'gradlew.bat' if the wrapper is present, otherwise to 'gradle'."
|
26
26
|
class_option :maven_include_groups, desc: "Whether dependency name should include group id. Only meaningful if used with a Java/maven project. Defaults to false."
|
27
|
+
class_option :maven_options, desc: "Maven options to append to command. Defaults to empty."
|
27
28
|
class_option :rebar_command, desc: "Command to use when fetching rebar packages. Only meaningful if used with a Erlang/rebar project. Defaults to 'rebar'."
|
28
29
|
class_option :rebar_deps_dir, desc: "Path to rebar dependencies directory. Only meaningful if used with a Erlang/rebar project. Defaults to 'deps'."
|
29
30
|
class_option :subprojects, type: :array, desc: "Generate a single report for multiple sub-projects. Ex: --subprojects='path/to/project1', 'path/to/project2'"
|
@@ -34,12 +35,18 @@ module LicenseFinder
|
|
34
35
|
desc "action_items", "List unapproved dependencies (the default action for `license_finder`)"
|
35
36
|
|
36
37
|
def action_items
|
38
|
+
any_packages = license_finder.any_packages?
|
37
39
|
unapproved = license_finder.unapproved
|
38
40
|
blacklisted = license_finder.blacklisted
|
39
41
|
|
40
42
|
# Ensure to start output on a new line even with dot progress indicators.
|
41
43
|
say "\n"
|
42
44
|
|
45
|
+
unless any_packages
|
46
|
+
say "No dependencies recognized!", :red
|
47
|
+
exit 0
|
48
|
+
end
|
49
|
+
|
43
50
|
if unapproved.empty?
|
44
51
|
say "All dependencies are approved for use", :green
|
45
52
|
else
|
data/lib/license_finder/core.rb
CHANGED
@@ -37,7 +37,7 @@ module LicenseFinder
|
|
37
37
|
end
|
38
38
|
|
39
39
|
extend Forwardable
|
40
|
-
def_delegators :decision_applier, :acknowledged, :unapproved, :blacklisted
|
40
|
+
def_delegators :decision_applier, :acknowledged, :unapproved, :blacklisted, :any_packages?
|
41
41
|
|
42
42
|
def project_name
|
43
43
|
decisions.project_name || config.project_path.basename.to_s
|
@@ -68,10 +68,10 @@ module LicenseFinder
|
|
68
68
|
gradle_command: config.gradle_command,
|
69
69
|
gradle_include_groups: config.gradle_include_groups,
|
70
70
|
maven_include_groups: config.maven_include_groups,
|
71
|
+
maven_options: config.maven_options,
|
71
72
|
rebar_command: config.rebar_command,
|
72
73
|
rebar_deps_dir: config.rebar_deps_dir,
|
73
74
|
)
|
74
75
|
end
|
75
76
|
end
|
76
77
|
end
|
77
|
-
|
@@ -2,7 +2,8 @@ module LicenseFinder
|
|
2
2
|
class DecisionApplier
|
3
3
|
def initialize(options)
|
4
4
|
@decisions = options.fetch(:decisions)
|
5
|
-
@
|
5
|
+
@all_packages = decisions.packages + options.fetch(:packages)
|
6
|
+
@acknowledged = apply_decisions
|
6
7
|
end
|
7
8
|
|
8
9
|
attr_reader :acknowledged
|
@@ -15,12 +16,15 @@ module LicenseFinder
|
|
15
16
|
acknowledged.select(&:blacklisted?)
|
16
17
|
end
|
17
18
|
|
19
|
+
def any_packages?
|
20
|
+
all_packages.any?
|
21
|
+
end
|
22
|
+
|
18
23
|
private
|
19
24
|
|
20
|
-
attr_reader :decisions
|
25
|
+
attr_reader :decisions, :all_packages
|
21
26
|
|
22
|
-
def apply_decisions
|
23
|
-
all_packages = decisions.packages + system_packages
|
27
|
+
def apply_decisions
|
24
28
|
all_packages
|
25
29
|
.map { |package| with_decided_licenses(package) }
|
26
30
|
.map { |package| with_approval(package) }
|
@@ -40,19 +40,15 @@ module LicenseFinder
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def acknowledgements_path
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
]
|
48
|
-
|
49
|
-
directories
|
50
|
-
.map { |dir| project_path.join(dir, filename) }
|
51
|
-
.find(&:exist?)
|
43
|
+
search_paths = [ "Pods/Pods-acknowledgements.plist",
|
44
|
+
"Pods/Target Support Files/Pods/Pods-acknowledgements.plist",
|
45
|
+
"Pods/Target Support Files/Pods-*/Pods-*-acknowledgements.plist" ]
|
46
|
+
|
47
|
+
Dir[*search_paths.map {|path| File.join(project_path, path) }].first
|
52
48
|
end
|
53
49
|
|
54
50
|
def read_plist pathname
|
55
|
-
JSON.parse(`plutil -convert json -o - '#{pathname
|
51
|
+
JSON.parse(`plutil -convert json -o - '#{pathname}'`)
|
56
52
|
end
|
57
53
|
end
|
58
54
|
end
|
@@ -55,8 +55,10 @@ module LicenseFinder
|
|
55
55
|
# checked in. Canonical paths are only checked by `go get'. We
|
56
56
|
# discovered that `go list' will print a warning and unfortunately exit
|
57
57
|
# with status code 1. Setting GOPATH to nil removes those warnings.
|
58
|
+
orig_gopath = ENV['GOPATH']
|
58
59
|
ENV['GOPATH'] = nil
|
59
60
|
val = capture('go list -f "{{join .Deps \"\n\"}}" ./...')
|
61
|
+
ENV['GOPATH'] = orig_gopath
|
60
62
|
return [] unless val.last
|
61
63
|
# Select non-standard packages. `go list std` returns the list of standard
|
62
64
|
# dependencies. We then filter those dependencies out of the full list of
|
@@ -70,8 +70,10 @@ module LicenseFinder
|
|
70
70
|
# checked in. Canonical paths are only checked by `go get'. We
|
71
71
|
# discovered that `go list' will print a warning and unfortunately exit
|
72
72
|
# with status code 1. Setting GOPATH to nil removes those warnings.
|
73
|
+
orig_gopath = ENV['GOPATH']
|
73
74
|
ENV['GOPATH'] = nil
|
74
75
|
val = capture('go list -f "{{join .Deps \"\n\"}}" ./...')
|
76
|
+
ENV['GOPATH'] = orig_gopath
|
75
77
|
raise 'go list failed' unless val.last
|
76
78
|
# Select non-standard packages. `go list std` returns the list of standard
|
77
79
|
# dependencies. We then filter those dependencies out of the full list of
|
@@ -7,12 +7,13 @@ module LicenseFinder
|
|
7
7
|
super
|
8
8
|
@ignored_groups = options[:ignored_groups]
|
9
9
|
@include_groups = options[:maven_include_groups]
|
10
|
+
@maven_options = options[:maven_options]
|
10
11
|
end
|
11
12
|
|
12
13
|
def current_packages
|
13
14
|
command = "#{package_management_command} org.codehaus.mojo:license-maven-plugin:download-licenses"
|
14
15
|
command += " -Dlicense.excludedScopes=#{@ignored_groups.to_a.join(',')}" if @ignored_groups and !@ignored_groups.empty?
|
15
|
-
|
16
|
+
command += " #{@maven_options}" if !@maven_options.nil?
|
16
17
|
output, success = Dir.chdir(project_path) { capture(command) }
|
17
18
|
raise "Command '#{command}' failed to execute: #{output}" unless success
|
18
19
|
|
@@ -1,88 +1,96 @@
|
|
1
|
-
require '
|
1
|
+
require 'yajl'
|
2
|
+
require 'tempfile'
|
2
3
|
|
3
4
|
module LicenseFinder
|
4
5
|
class NPM < PackageManager
|
5
6
|
DEPENDENCY_GROUPS = ["dependencies", "devDependencies"]
|
6
7
|
|
7
8
|
def current_packages
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
if packages[package_id] && packages[package_id].version.nil? && dependency["version"]
|
14
|
-
old_package = packages[package_id]
|
15
|
-
packages[package_id] = NpmPackage.new(dependency, logger: logger, groups: old_package.groups)
|
16
|
-
else
|
17
|
-
packages[package_id] ||= NpmPackage.new(dependency, logger: logger)
|
18
|
-
end
|
19
|
-
packages[package_id].groups << group_name unless packages[package_id].groups.include?(group_name)
|
9
|
+
top_level_deps = npm_json['dependencies']&.values || []
|
10
|
+
package_json = JSON.parse(File.read(package_path), :max_nesting => false)
|
11
|
+
top_level_deps.each do |dep|
|
12
|
+
dep['groups'] = DEPENDENCY_GROUPS.select do |group|
|
13
|
+
package_json[group]&.keys&.include? dep['name']
|
20
14
|
end
|
21
15
|
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
def self.package_management_command
|
26
|
-
"npm"
|
16
|
+
dependency_matches = flatten(top_level_deps)
|
17
|
+
dependency_matches = dependency_matches.group_by {|dep| [dep['name'], dep['version']]}
|
18
|
+
dependency_matches.map {|id, dep_matches| construct_npm_package(dep_matches, id)}
|
27
19
|
end
|
28
20
|
|
29
21
|
private
|
30
22
|
|
31
|
-
def
|
32
|
-
|
33
|
-
DEPENDENCY_GROUPS.map do |group|
|
34
|
-
package_json.fetch(group, {}).keys.map do |dependency|
|
35
|
-
{
|
36
|
-
group: group,
|
37
|
-
name: dependency
|
38
|
-
}
|
39
|
-
end
|
40
|
-
end.flatten
|
23
|
+
def self.package_management_command
|
24
|
+
"npm"
|
41
25
|
end
|
42
26
|
|
43
|
-
def
|
44
|
-
|
45
|
-
deps = @json.fetch("dependencies", {}).reject { |_,d| d.is_a?(String) }
|
46
|
-
current_dep = deps[dependency]
|
47
|
-
block.call(current_dep) if current_dep
|
48
|
-
recursive_dependencies(current_dep) do |d|
|
49
|
-
block.call(d)
|
50
|
-
end
|
27
|
+
def package_path
|
28
|
+
project_path.join('package.json')
|
51
29
|
end
|
52
30
|
|
53
31
|
def npm_json
|
54
|
-
|
55
|
-
|
32
|
+
tempfile = Tempfile.new
|
33
|
+
begin
|
34
|
+
command = "#{NPM::package_management_command} list --json --long > #{tempfile.path}"
|
35
|
+
output, success = Dir.chdir(project_path) { capture(command) }
|
56
36
|
|
57
|
-
|
58
|
-
|
59
|
-
else
|
60
|
-
json = begin
|
61
|
-
JSON(output, :max_nesting => false)
|
62
|
-
rescue JSON::ParserError
|
63
|
-
nil
|
64
|
-
end
|
65
|
-
if json
|
66
|
-
$stderr.puts "Command '#{command}' returned an error but parsing succeeded."
|
37
|
+
if success
|
38
|
+
json = Yajl::Parser.parse(File.open(tempfile.path))
|
67
39
|
else
|
68
|
-
|
40
|
+
json = begin
|
41
|
+
Yajl::Parser.parse(File.open(tempfile.path))
|
42
|
+
rescue Yajl::ParseError
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
if json
|
46
|
+
$stderr.puts "Command '#{command}' returned an error but parsing succeeded."
|
47
|
+
else
|
48
|
+
raise "Command '#{command}' failed to execute: #{output}"
|
49
|
+
end
|
69
50
|
end
|
51
|
+
ensure
|
52
|
+
tempfile.close
|
53
|
+
tempfile.unlink
|
70
54
|
end
|
71
|
-
|
72
55
|
json
|
73
56
|
end
|
74
57
|
|
75
|
-
def
|
76
|
-
|
58
|
+
def flatten(list)
|
59
|
+
list.inject [] {|acc, dep| acc + [dep] + flatten(dep['dependencies']&.values&.map {|inner_dep| inner_dep['groups'] = dep['groups']; inner_dep} || [])}
|
77
60
|
end
|
78
61
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
node_module.fetch('dependencies', {}).each do |dep_key, data|
|
83
|
-
data['name'] ||= dep_key
|
84
|
-
recursive_dependencies(data, &block)
|
62
|
+
def licenses(dep_matches)
|
63
|
+
licenses_lists = dep_matches.map do |match|
|
64
|
+
match['licenses']
|
85
65
|
end
|
66
|
+
|
67
|
+
licenses_lists.reject! {|licenses| licenses.nil? || licenses == '[Circular]'}
|
68
|
+
licenses_lists = licenses_lists.uniq
|
69
|
+
case licenses_lists.count
|
70
|
+
when 0
|
71
|
+
dep_matches.map {|dep_match| dep_match['license']}.reject(&:nil?).uniq
|
72
|
+
when 1
|
73
|
+
licenses_lists.first.map {|license| license['type']}
|
74
|
+
else
|
75
|
+
raise "Varying lists of licenses provided for #{dep_matches.first['name']} (#{dep_matches.first['version']})"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def construct_npm_package(dep_matches, id)
|
80
|
+
name, version = id
|
81
|
+
dependencies = value_from_matches(dep_matches, 'dependencies')&.values&.map {|d| d['name']} || []
|
82
|
+
NpmPackage.new(name, version,
|
83
|
+
homepage: value_from_matches(dep_matches, 'homepage'),
|
84
|
+
description: value_from_matches(dep_matches, 'description'),
|
85
|
+
spec_licenses: licenses(dep_matches),
|
86
|
+
install_path: value_from_matches(dep_matches, 'path'),
|
87
|
+
dependencies: dependencies,
|
88
|
+
groups: dep_matches.map {|match| match['groups']}.flatten.uniq,
|
89
|
+
logger: logger)
|
90
|
+
end
|
91
|
+
|
92
|
+
def value_from_matches(dep_matches, key)
|
93
|
+
dep_matches.map {|m| m[key]}.reject(&:nil?).uniq&.first
|
86
94
|
end
|
87
95
|
end
|
88
96
|
end
|