summaryrefslogtreecommitdiff
path: root/lib/license/finder/ext/yarn.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/license/finder/ext/yarn.rb')
-rw-r--r--lib/license/finder/ext/yarn.rb89
1 files changed, 87 insertions, 2 deletions
diff --git a/lib/license/finder/ext/yarn.rb b/lib/license/finder/ext/yarn.rb
index cc2c029..dba096b 100644
--- a/lib/license/finder/ext/yarn.rb
+++ b/lib/license/finder/ext/yarn.rb
@@ -2,8 +2,93 @@
module LicenseFinder
class Yarn
- def prepare_command
- 'yarn install --ignore-engines --ignore-scripts'
+ INCOMPATIBLE_PACKAGE_REGEX = /(?<name>[\w,\-]+)@(?<version>(\d+\.?)+)/.freeze
+ PHANTOM_PACKAGE_REGEX = /workspace-aggregator-[a-zA-Z0-9]{8}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{4}-[a-zA-Z0-9]{12}/.freeze
+
+ def possible_package_paths
+ [project_path.join('yarn.lock')]
+ end
+
+ def current_packages
+ stdout, _stderr, status = Dir.chdir(project_path) do
+ shell.execute(list_licenses_command)
+ end
+ return [] unless status.success?
+
+ stdout.each_line.flat_map do |line|
+ dependencies_from(JSON.parse(line))
+ end
+ end
+
+ def prepare
+ Dir.chdir(project_path) do
+ shell.execute([
+ :yarn, :install,
+ '--ignore-engines', '--ignore-scripts',
+ '--production'
+ ])
+ end
+ end
+
+ private
+
+ def list_licenses_command
+ [
+ :yarn,
+ :licenses,
+ :list,
+ '--no-progress',
+ '--json',
+ '--production',
+ '--cwd',
+ project_path || Pathname.pwd
+ ]
+ end
+
+ def install_path_for(name)
+ if project_path
+ project_path.join('node_modules', name)
+ else
+ Pathname.pwd.join('node_modules', name)
+ end
+ end
+
+ def map_from(hash)
+ name = hash['Name']
+
+ YarnPackage.new(
+ name,
+ hash['Version'],
+ spec_licenses: [hash['License']],
+ install_path: install_path_for(name).to_s,
+ homepage: hash['VendorUrl']
+ )
+ end
+
+ def dependencies_from(json)
+ case json['type']
+ when 'table'
+ from_json_table(json)
+ when 'info'
+ from_json_info(json)
+ else
+ []
+ end
+ end
+
+ def from_json_table(json)
+ head = json['data']['head']
+ json['data']['body'].map do |array|
+ hash = Hash[head.zip(array)]
+ map_from(hash) unless PHANTOM_PACKAGE_REGEX.match(hash['Name'])
+ end.compact
+ end
+
+ def from_json_info(json)
+ matches = json['data'].to_s.match(INCOMPATIBLE_PACKAGE_REGEX)
+ return [] unless matches
+
+ [YarnPackage.new(matches['name'], matches['version'], spec_licenses: ['unknown'])]
end
end
end