class Importmap::Commands
def self.exit_on_failure?
def self.exit_on_failure? false end
def audit
def audit vulnerable_packages = npm.vulnerable_packages if vulnerable_packages.any? table = [["Package", "Severity", "Vulnerable versions", "Vulnerability"]] vulnerable_packages.each { |p| table << [p.name, p.severity, p.vulnerable_versions, p.vulnerability] } puts_table(table) vulnerabilities = 'vulnerability'.pluralize(vulnerable_packages.size) severities = vulnerable_packages.map(&:severity).tally.sort_by(&:last).reverse .map { |severity, count| "#{count} #{severity}" } .join(", ") puts " #{vulnerable_packages.size} #{vulnerabilities} found: #{severities}" exit 1 else puts "No vulnerable packages found" end end
def json
def json require Rails.root.join("config/environment") puts Rails.application.importmap.to_json(resolver: ActionController::Base.helpers) end
def npm
def npm @npm ||= Importmap::Npm.new end
def outdated
def outdated if (outdated_packages = npm.outdated_packages).any? table = [["Package", "Current", "Latest"]] outdated_packages.each { |p| table << [p.name, p.current_version, p.latest_version || p.error] } puts_table(table) packages = 'package'.pluralize(outdated_packages.size) puts " #{outdated_packages.size} outdated #{packages} found" exit 1 else puts "No outdated packages found" end end
def packager
def packager @packager ||= Importmap::Packager.new end
def packages
def packages puts npm.packages_with_versions.map { |x| x.join(' ') } end
def pin(*packages)
def pin(*packages) if imports = packager.import(*packages, env: options[:env], from: options[:from]) imports.each do |package, url| puts %(Pinning "#{package}" to #{packager.vendor_path}/#{package}.js via download from #{url}) packager.download(package, url) pin = packager.vendored_pin_for(package, url) if packager.packaged?(package) gsub_file("config/importmap.rb", /^pin "#{package}".*$/, pin, verbose: false) else append_to_file("config/importmap.rb", "#{pin}\n", verbose: false) end end else puts "Couldn't find any packages in #{packages.inspect} on #{options[:from]}" end end
def pristine
def pristine packages = npm.packages_with_versions.map do |p, v| v.blank? ? p : [p, v].join("@") end if imports = packager.import(*packages, env: options[:env], from: options[:from]) imports.each do |package, url| puts %(Downloading "#{package}" to #{packager.vendor_path}/#{package}.js from #{url}) packager.download(package, url) end else puts "Couldn't find any packages in #{packages.inspect} on #{options[:from]}" end end
def puts_table(array)
def puts_table(array) column_sizes = array.reduce([]) do |lengths, row| row.each_with_index.map{ |iterand, index| [lengths[index] || 0, iterand.to_s.length].max } end divider = "|" + (column_sizes.map { |s| "-" * (s + 2) }.join('|')) + '|' array.each_with_index do |row, row_number| row = row.fill(nil, row.size..(column_sizes.size - 1)) row = row.each_with_index.map { |v, i| v.to_s + " " * (column_sizes[i] - v.to_s.length) } puts "| " + row.join(" | ") + " |" puts divider if row_number == 0 end end
def remove_line_from_file(path, pattern)
def remove_line_from_file(path, pattern) path = File.expand_path(path, destination_root) all_lines = File.readlines(path) with_lines_removed = all_lines.select { |line| line !~ pattern } File.open(path, "w") do |file| with_lines_removed.each { |line| file.write(line) } end end
def unpin(*packages)
def unpin(*packages) if imports = packager.import(*packages, env: options[:env], from: options[:from]) imports.each do |package, url| if packager.packaged?(package) puts %(Unpinning and removing "#{package}") packager.remove(package) end end else puts "Couldn't find any packages in #{packages.inspect} on #{options[:from]}" end end
def update
def update if (outdated_packages = npm.outdated_packages).any? pin(*outdated_packages.map(&:name)) else puts "No outdated packages found" end end