From 8d5c86b90510b797edfdfe625bea6b1b42eed9e6 Mon Sep 17 00:00:00 2001 From: Carlos Palhares Date: Sat, 13 Aug 2022 13:46:34 -0300 Subject: [PATCH] Load yarn packages without reading their package files --- .rubocop.yml | 3 + lib/cobra_commander.rb | 2 +- lib/cobra_commander/dependencies.rb | 2 +- lib/cobra_commander/dependencies/yarn.rb | 49 +++++++++++++++++ .../dependencies/yarn/package.rb | 35 ++++-------- .../dependencies/yarn/package_repo.rb | 32 ----------- .../dependencies/yarn_workspace.rb | 55 ------------------- 7 files changed, 64 insertions(+), 114 deletions(-) create mode 100644 lib/cobra_commander/dependencies/yarn.rb delete mode 100644 lib/cobra_commander/dependencies/yarn/package_repo.rb delete mode 100644 lib/cobra_commander/dependencies/yarn_workspace.rb diff --git a/.rubocop.yml b/.rubocop.yml index dbcfa13f..d0f9516d 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -8,3 +8,6 @@ Rails: Gemspec/RequireMFA: Enabled: false + +Style/ClassAndModuleChildren: + Enabled: false diff --git a/lib/cobra_commander.rb b/lib/cobra_commander.rb index 40f83c61..960c85f4 100644 --- a/lib/cobra_commander.rb +++ b/lib/cobra_commander.rb @@ -13,7 +13,7 @@ module CobraCommander def self.umbrella(root_path, yarn: false, bundler: false, name: UMBRELLA_APP_NAME) umbrella = Umbrella.new(name, root_path) - umbrella.add_source(:yarn, Dependencies::YarnWorkspace.new(root_path)) unless bundler + umbrella.add_source(:yarn, Dependencies::Yarn.new(root_path)) unless bundler umbrella.add_source(:bundler, Dependencies::Bundler.new(root_path)) unless yarn umbrella end diff --git a/lib/cobra_commander/dependencies.rb b/lib/cobra_commander/dependencies.rb index cad01e75..f43d8289 100644 --- a/lib/cobra_commander/dependencies.rb +++ b/lib/cobra_commander/dependencies.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true -require_relative "dependencies/yarn_workspace" +require_relative "dependencies/yarn" require_relative "dependencies/bundler" diff --git a/lib/cobra_commander/dependencies/yarn.rb b/lib/cobra_commander/dependencies/yarn.rb new file mode 100644 index 00000000..d5c014b4 --- /dev/null +++ b/lib/cobra_commander/dependencies/yarn.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require "json" +require "open3" + +module CobraCommander + module Dependencies + # Yarn workspace components source for an umbrella + class Yarn + autoload :Package, "cobra_commander/dependencies/yarn/package" + + def initialize(root_path) + @root_path = root_path + end + + def path + @root_path + end + + def dependencies + packages.map(&:name) + end + + def components + @components ||= packages.map do |package| + { + path: package.path, + name: package.name, + dependencies: package.dependencies, + } + end + end + + private + + def packages + @packages ||= begin + output, = Open3.capture2("yarn workspaces --json info", chdir: @root_path) + JSON.parse(JSON.parse(output)["data"]).map do |name, spec| + Package.new( + File.join(@root_path, spec["location"]), + name, spec["workspaceDependencies"] + ) + end + end + end + end + end +end diff --git a/lib/cobra_commander/dependencies/yarn/package.rb b/lib/cobra_commander/dependencies/yarn/package.rb index 3aeda630..5257d72f 100644 --- a/lib/cobra_commander/dependencies/yarn/package.rb +++ b/lib/cobra_commander/dependencies/yarn/package.rb @@ -1,37 +1,22 @@ # frozen_string_literal: true -require "json" require "pathname" module CobraCommander module Dependencies - module Yarn - # Represents an Yarn package.json file - class Package - attr_reader :path + class Yarn::Package + attr_reader :path, :name, :dependencies - def initialize(path) - @path = ::Pathname.new(File.join(path, "package.json")).realpath - end - - def project_tag - name.match(%r{^@[\w-]+/}).to_s - end - - def name - json["name"] - end - - def dependencies - json.fetch("dependencies", {}) - .merge(json.fetch("devDependencies", {})) - end + def initialize(path, name, dependencies) + @path = ::Pathname.new(File.join(path, "package.json")).realpath + @name = untag(name) + @dependencies = dependencies.map { |dep| untag(dep) } + end - private + private - def json - @json ||= JSON.parse(File.read(@path)) - end + def untag(name) + name.gsub(%r{^@[\w-]+/}, "") end end end diff --git a/lib/cobra_commander/dependencies/yarn/package_repo.rb b/lib/cobra_commander/dependencies/yarn/package_repo.rb deleted file mode 100644 index 10009aa3..00000000 --- a/lib/cobra_commander/dependencies/yarn/package_repo.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -module CobraCommander - module Dependencies - module Yarn - # Yarn package repository to load and cache package.json files - class PackageRepo - def initialize - @specs = {} - end - - def specs - @specs.values - end - - def load_linked_specs(package) - package.dependencies.each_value do |spec| - next unless spec =~ /link:(.+)/ - - load_spec(File.join(package.path, "..", Regexp.last_match(1))) - end - end - - def load_spec(path) - @specs[path] ||= Package.new(path).tap do |package| - load_linked_specs(package) - end - end - end - end - end -end diff --git a/lib/cobra_commander/dependencies/yarn_workspace.rb b/lib/cobra_commander/dependencies/yarn_workspace.rb deleted file mode 100644 index 5b5ccee8..00000000 --- a/lib/cobra_commander/dependencies/yarn_workspace.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true - -require "open3" - -require_relative "yarn/package" -require_relative "yarn/package_repo" - -module CobraCommander - module Dependencies - # Yarn workspace components source for an umbrella - class YarnWorkspace - attr_reader :packages - - def initialize(root_path) - @repo = Yarn::PackageRepo.new - @root_package = Yarn::Package.new(root_path) - @repo.load_linked_specs(@root_package) - load_workspace_packages - end - - def path - @root_package.path - end - - def dependencies - workspace_spec.keys.map(&method(:untag)) - end - - def components - @repo.specs.map do |spec| - { path: spec.path, name: untag(spec.name), dependencies: spec.dependencies.keys.map(&method(:untag)) } - end - end - - private - - def load_workspace_packages - workspace_spec.map do |_name, spec| - @repo.load_spec File.expand_path(File.join(@root_package.path, "..", spec["location"])) - end - end - - def workspace_spec - @workspace_spec ||= begin - output, = Open3.capture2("yarn workspaces --json info", chdir: File.dirname(@root_package.path)) - JSON.parse(JSON.parse(output)["data"]) - end - end - - def untag(name) - name.gsub(@root_package.project_tag, "") - end - end - end -end