class PoiseJavascript::Resources::NodePackage::Provider
The default provider for the `node_package` resource.
@see Resource
Public Instance Methods
Populate current and candidate versions for all needed packages.
@api private @param resource [PoiseJavascript::Resources::NodePackage::Resource]
Resource to load for.
@return [void]
# File lib/poise_javascript/resources/node_package.rb, line 116 def check_package_versions(resource) version_data = Hash.new {|hash, key| hash[key] = {current: nil, candidate: nil} } # Get the version for everything currently installed. list_args = npm_version?('>= 1.4.16') ? %w{--depth 0} : [] npm_shell_out!('list', list_args).fetch('dependencies', {}).each do |pkg_name, pkg_data| version_data[pkg_name][:current] = pkg_data['version'] end # If any requested packages are currently installed, run npm outdated # to look for candidate versions. Older npm doesn't support --json # here so you get slow behavior, sorry. requested_packages = Set.new(Array(resource.package_name)) if npm_version?('>= 1.3.16') && version_data.any? {|pkg_name, _pkg_vers| requested_packages.include?(pkg_name) } outdated = npm_shell_out!('outdated') || {} version_data.each do |pkg_name, pkg_vers| pkg_vers[:candidate] = if outdated.include?(pkg_name) outdated[pkg_name]['wanted'] else # If it was already installed and not listed in outdated, it # must have been up to date already. pkg_vers[:current] end end end # Check for candidates for anything else we didn't get from outdated. requested_packages.each do |pkg_name| version_data[pkg_name][:candidate] ||= npm_shell_out!('show', [pkg_name])['version'] end # Populate the current resource and candidate versions. Youch this is # a gross mix of data flow. if(resource.package_name.is_a?(Array)) @candidate_version = [] versions = [] [resource.package_name].flatten.each do |name| ver = version_data[name.downcase] versions << ver[:current] @candidate_version << ver[:candidate] end resource.version(versions) else ver = version_data[resource.package_name.downcase] resource.version(ver[:current]) @candidate_version = ver[:candidate] end end
Install package(s) using npm.
@param name [String, Array<String>] Name(s) of package(s). @param version [String, Array<String>] Version(s) of package(s). @return [void]
# File lib/poise_javascript/resources/node_package.rb, line 166 def install_package(name, version) args = [] # Set --unsafe-perm unless the property is nil. unless new_resource.unsafe_perm.nil? args << '--unsafe-perm' args << new_resource.unsafe_perm.to_s end # Build up the actual package install args. if new_resource.source args << new_resource.source else Array(name).zip(Array(version)) do |pkg_name, pkg_ver| args << "#{pkg_name}@#{pkg_ver}" end end npm_shell_out!('install', args, parse_json: false) end
Load current and candidate versions for all needed packages.
@api private @return [Chef::Resource]
# File lib/poise_javascript/resources/node_package.rb, line 103 def load_current_resource @current_resource = new_resource.class.new(new_resource.name, run_context) current_resource.package_name(new_resource.package_name) check_package_versions(current_resource) current_resource end
Uninstall package(s) using npm.
@param name [String, Array<String>] Name(s) of package(s). @param version [String, Array<String>] Version(s) of package(s). @return [void]
# File lib/poise_javascript/resources/node_package.rb, line 192 def remove_package(name, version) npm_shell_out!('uninstall', [name].flatten, parse_json: false) end
Private Instance Methods
Run an npm command.
@param subcmd [String] Subcommand to run. @param args [Array<String>] Command arguments. @param parse_json [Boolean] Parse the JSON on stdout. @return [Hash]
# File lib/poise_javascript/resources/node_package.rb, line 204 def npm_shell_out!(subcmd, args=[], parse_json: true) cmd = [new_resource.npm_binary, subcmd, '--json'] # If path is nil, we are in global mode. cmd << '--global' unless new_resource.path # Add the rest. cmd.concat(args) # If we are in global mode, cwd will be nil so probably just fine. Add # the directory for the node binary to $PATH for post-install stuffs. new_path = [::File.dirname(new_resource.javascript), ENV['PATH'].to_s].join(::File::PATH_SEPARATOR) out = javascript_shell_out!(cmd, cwd: new_resource.path, group: new_resource.group, user: new_resource.user, environment: {'PATH' => new_path}) if parse_json # Parse the JSON. if out.stdout.strip.empty? {} else Chef::JSONCompat.parse(out.stdout) end else out end end
Find the version of the current npm binary.
@return [Gem::Version]
# File lib/poise_javascript/resources/node_package.rb, line 229 def npm_version @npm_version ||= begin out = javascript_shell_out!([new_resource.npm_binary, 'version']) # Older NPM doesn't support --json here we get to regex! # The line we want looks like: # npm: '2.12.1' if out.stdout =~ /npm: '([^']+)'/ Gem::Version.new($1) else raise PoiseJavascript::Error.new("Unable to parse NPM version from #{out.stdout.inspect}") end end end
Check the NPM version against a requirement.
@param req [String] Requirement string in Gem::Requirement format. @return [Boolean]
# File lib/poise_javascript/resources/node_package.rb, line 247 def npm_version?(req) Gem::Requirement.new(req).satisfied_by?(npm_version) end