diff options
Diffstat (limited to 'lib/license/finder/ext/yarn.rb')
| -rw-r--r-- | lib/license/finder/ext/yarn.rb | 89 |
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 |
