Vendor the external cookbooks
Knife-Zero doesn't include Berkshelf support, so vendoring everything in the repo is convenient again
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
autoload :Error, 'poise_javascript/error'
|
||||
autoload :Resources, 'poise_javascript/resources'
|
||||
autoload :JavascriptCommandMixin, 'poise_javascript/javascript_command_mixin'
|
||||
autoload :JavascriptProviders, 'poise_javascript/javascript_providers'
|
||||
autoload :VERSION, 'poise_javascript/version'
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'poise_javascript/resources'
|
||||
require 'poise_javascript/javascript_providers'
|
||||
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'poise_languages'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
class Error < PoiseLanguages::Error
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,56 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'poise/utils'
|
||||
require 'poise_languages'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
# Mixin for resources and providers which run Javascript commands.
|
||||
#
|
||||
# @since 1.0.0
|
||||
module JavascriptCommandMixin
|
||||
include Poise::Utils::ResourceProviderMixin
|
||||
|
||||
# Mixin for resources which run Javascript commands.
|
||||
module Resource
|
||||
include PoiseLanguages::Command::Mixin::Resource(:javascript, default_binary: 'node')
|
||||
|
||||
# @!attribute npm_binary
|
||||
# Path to the npm binary.
|
||||
# @return [String]
|
||||
attribute(:npm_binary, kind_of: String, default: lazy { default_npm_binary })
|
||||
|
||||
private
|
||||
|
||||
# Find the default gem binary. If there is a parent use that, otherwise
|
||||
# use the same logic as {PoiseRuby::RubyProviders::Base#npm_binary}.
|
||||
#
|
||||
# @return [String]
|
||||
def default_npm_binary
|
||||
if parent_javascript
|
||||
parent_javascript.npm_binary
|
||||
else
|
||||
::File.expand_path('../npm', javascript)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module Provider
|
||||
include PoiseLanguages::Command::Mixin::Provider(:javascript)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/platform/provider_priority_map'
|
||||
|
||||
require 'poise_javascript/javascript_providers/dummy'
|
||||
require 'poise_javascript/javascript_providers/iojs'
|
||||
require 'poise_javascript/javascript_providers/nodejs'
|
||||
require 'poise_javascript/javascript_providers/scl'
|
||||
require 'poise_javascript/javascript_providers/system'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
# Inversion providers for the javascript_runtime resource.
|
||||
#
|
||||
# @since 1.0.0
|
||||
module JavascriptProviders
|
||||
autoload :Base, 'poise_javascript/javascript_providers/base'
|
||||
|
||||
Chef::Platform::ProviderPriorityMap.instance.priority(:javascript_runtime, [
|
||||
PoiseJavascript::JavascriptProviders::IOJS,
|
||||
PoiseJavascript::JavascriptProviders::NodeJS,
|
||||
PoiseJavascript::JavascriptProviders::Scl,
|
||||
PoiseJavascript::JavascriptProviders::System,
|
||||
])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,97 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/provider'
|
||||
require 'poise'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module JavascriptProviders
|
||||
class Base < Chef::Provider
|
||||
include Poise(inversion: :javascript_runtime)
|
||||
|
||||
# Set default inversion options.
|
||||
#
|
||||
# @api private
|
||||
def self.default_inversion_options(node, new_resource)
|
||||
super.merge({
|
||||
version: new_resource.version,
|
||||
})
|
||||
end
|
||||
|
||||
# The `install` action for the `javascript_runtime` resource.
|
||||
#
|
||||
# @return [void]
|
||||
def action_install
|
||||
notifying_block do
|
||||
install_javascript
|
||||
end
|
||||
end
|
||||
|
||||
# The `uninstall` action for the `javascript_runtime` resource.
|
||||
#
|
||||
# @abstract
|
||||
# @return [void]
|
||||
def action_uninstall
|
||||
notifying_block do
|
||||
uninstall_javascript
|
||||
end
|
||||
end
|
||||
|
||||
# The path to the `javascript` binary. This is an output property.
|
||||
#
|
||||
# @abstract
|
||||
# @return [String]
|
||||
def javascript_binary
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# The environment variables for this Javascript. This is an output property.
|
||||
#
|
||||
# @return [Hash<String, String>]
|
||||
def javascript_environment
|
||||
{}
|
||||
end
|
||||
|
||||
# The path to the `npm` binary. This is an output property.
|
||||
#
|
||||
# @abstract
|
||||
# @return [String]
|
||||
def npm_binary
|
||||
::File.expand_path(::File.join('..', 'npm'), javascript_binary)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Install the Javascript runtime. Must be implemented by subclass.
|
||||
#
|
||||
# @abstract
|
||||
# @return [void]
|
||||
def install_javascript
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Uninstall the Javascript runtime. Must be implemented by subclass.
|
||||
#
|
||||
# @abstract
|
||||
# @return [void]
|
||||
def uninstall_javascript
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,77 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'poise_javascript/javascript_providers/base'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module JavascriptProviders
|
||||
# Inversion provider for the `javascript_runtime` resource to use a fake Javascript,
|
||||
# for use in unit tests.
|
||||
#
|
||||
# @since 1.0.0
|
||||
# @provides dummy
|
||||
class Dummy < Base
|
||||
provides(:dummy)
|
||||
|
||||
def self.default_inversion_options(node, resource)
|
||||
super.merge({
|
||||
# Manual overrides for dummy data.
|
||||
javascript_binary: ::File.join('', 'node'),
|
||||
javascript_environment: nil,
|
||||
npm_binary: nil,
|
||||
})
|
||||
end
|
||||
|
||||
# The `install` action for the `javascript_runtime` resource.
|
||||
#
|
||||
# @return [void]
|
||||
def action_install
|
||||
# This space left intentionally blank.
|
||||
end
|
||||
|
||||
# The `uninstall` action for the `javascript_runtime` resource.
|
||||
#
|
||||
# @return [void]
|
||||
def action_uninstall
|
||||
# This space left intentionally blank.
|
||||
end
|
||||
|
||||
# Path to the non-existent Javascript.
|
||||
#
|
||||
# @return [String]
|
||||
def javascript_binary
|
||||
options['javascript_binary']
|
||||
end
|
||||
|
||||
# Environment for the non-existent Javascript.
|
||||
#
|
||||
# @return [String]
|
||||
def javascript_environment
|
||||
options['javascript_environment'] || super
|
||||
end
|
||||
|
||||
# Path to the non-existent npm.
|
||||
#
|
||||
# @return [String]
|
||||
def npm_binary
|
||||
options['npm_binary'] || super
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/resource'
|
||||
require 'poise_languages/static'
|
||||
|
||||
require 'poise_javascript/error'
|
||||
require 'poise_javascript/javascript_providers/base'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module JavascriptProviders
|
||||
class IOJS < Base
|
||||
provides(:iojs)
|
||||
include PoiseLanguages::Static(
|
||||
versions: %w{3.3.1 3.2.0 3.1.0 3.0.0 2.5.0 2.4.0 2.3.4 2.2.1 2.1.0 2.0.2 1.8.4 1.7.1 1.6.4 1.5.1 1.4.3 1.3.0 1.2.0 1.1.0 1.0.4},
|
||||
machines: %w{linux-i686 linux-x86_64 darwin-x86_64},
|
||||
url: 'https://iojs.org/dist/v%{version}/iojs-v%{version}-%{kernel}-%{machine}.tar.gz',
|
||||
)
|
||||
|
||||
def self.provides_auto?(node, resource)
|
||||
# Also work if we have a version starting with 1. 2. or 3. since that has
|
||||
# to be io.js and no other mechanism supports that.
|
||||
super || (resource.version.to_s =~ /^[123](\.|$)/ && static_machines.include?(static_machine_label(node)))
|
||||
end
|
||||
|
||||
MACHINE_LABELS = {'i386' => 'x86', 'i686' => 'x86', 'x86_64' => 'x64'}
|
||||
|
||||
def static_url_variables
|
||||
machine = node['kernel']['machine']
|
||||
super.merge(machine: MACHINE_LABELS[machine] || machine)
|
||||
end
|
||||
|
||||
def javascript_binary
|
||||
::File.join(static_folder, 'bin', 'iojs')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def install_javascript
|
||||
install_static
|
||||
end
|
||||
|
||||
def uninstall_javascript
|
||||
uninstall_static
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/resource'
|
||||
require 'poise_languages/static'
|
||||
|
||||
require 'poise_javascript/error'
|
||||
require 'poise_javascript/javascript_providers/base'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module JavascriptProviders
|
||||
class NodeJS < Base
|
||||
provides(:nodejs)
|
||||
include PoiseLanguages::Static(
|
||||
# LTS version is first so that it is what you get for version ''.
|
||||
versions: %w{8.11.1 10.0.0 9.11.1 9.10.1 9.9.0 9.8.0 9.7.1 9.6.1 9.5.0 9.4.0 9.3.0 9.2.1 9.1.0 9.0.0 8.10.0 8.9.4 8.8.1 8.7.0 8.6.0 8.5.0 8.4.0 8.3.0 8.2.1 8.1.4 8.0.0 7.10.1 7.9.0 7.8.0 7.7.4 7.6.0 7.5.0 7.4.0 7.3.0 7.2.1 7.1.0 7.0.0 6.14.2 6.13.1 6.12.3 6.11.5 6.10.3 6.9.5 6.8.1 6.7.0 6.6.0 6.5.0 6.4.0 6.3.1 6.2.2 6.1.0 6.0.0 5.12.0 5.11.1 5.10.1 5.9.1 5.8.0 5.7.1 5.6.0 5.5.0 5.4.1 5.3.0 5.2.0 5.1.1 5.0.0 4.9.1 4.8.7 4.7.3 4.6.2 4.5.0 4.4.7 4.3.2 4.2.6 4.1.2 4.0.0 0.12.18 0.11.16 0.10.48 0.9.12 0.8.28 0.7.12 0.6.21 0.5.10 0.4.12 0.3.8 0.2.6 0.1.104},
|
||||
machines: %w{linux-i686 linux-x86_64 linux-armv6l linux-armv7l linux-arm64 darwin-x86_64},
|
||||
url: 'https://nodejs.org/dist/v%{version}/node-v%{version}-%{kernel}-%{machine}.tar.gz',
|
||||
)
|
||||
|
||||
def self.provides_auto?(node, resource)
|
||||
# Also work if we have a blank or numeric-y version. This should make
|
||||
# it the default provider on supported platforms.
|
||||
super || (resource.version.to_s =~ /^(\d|$)/ && static_machines.include?(static_machine_label(node)))
|
||||
end
|
||||
|
||||
MACHINE_LABELS = {'i386' => 'x86', 'i686' => 'x86', 'x86_64' => 'x64'}
|
||||
|
||||
def static_url_variables
|
||||
machine = node['kernel']['machine']
|
||||
super.merge(machine: MACHINE_LABELS[machine] || machine)
|
||||
end
|
||||
|
||||
def javascript_binary
|
||||
::File.join(static_folder, 'bin', 'node')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def install_javascript
|
||||
install_static
|
||||
end
|
||||
|
||||
def uninstall_javascript
|
||||
uninstall_static
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/resource'
|
||||
require 'poise_languages'
|
||||
|
||||
require 'poise_javascript/error'
|
||||
require 'poise_javascript/javascript_providers/base'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module JavascriptProviders
|
||||
class Scl < Base
|
||||
include PoiseLanguages::Scl::Mixin
|
||||
provides(:scl)
|
||||
scl_package('4.4.2', 'rh-nodejs4', 'rh-nodejs4-nodejs-devel', '>= 7.0')
|
||||
scl_package('0.10.35', 'nodejs010', 'nodejs010-nodejs-devel')
|
||||
|
||||
def javascript_binary
|
||||
::File.join(scl_folder, 'root', 'usr', 'bin', 'node')
|
||||
end
|
||||
|
||||
def javascript_environment
|
||||
scl_environment
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def install_javascript
|
||||
install_scl_package
|
||||
end
|
||||
|
||||
def uninstall_javascript
|
||||
uninstall_scl_package
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/resource'
|
||||
require 'poise_languages'
|
||||
|
||||
require 'poise_javascript/error'
|
||||
require 'poise_javascript/javascript_providers/base'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module JavascriptProviders
|
||||
class System < Base
|
||||
include PoiseLanguages::System::Mixin
|
||||
provides(:system)
|
||||
packages('nodejs', {
|
||||
debian: {default: %w{nodejs}},
|
||||
ubuntu: {default: %w{nodejs}},
|
||||
# Empty arrays because no package in the base OS.
|
||||
redhat: {default: %w{}},
|
||||
centos: {default: %w{}},
|
||||
fedora: {default: %w{nodejs}},
|
||||
amazon: {default: %w{}},
|
||||
})
|
||||
|
||||
def self.provides_auto?(node, resource)
|
||||
# Don't auto on platforms I know have no system package by default. Kind
|
||||
# of pointless since the nodejs provider will hit on these platforms
|
||||
# anyway so this shouldn't ever happen.
|
||||
super && !node.platform_family?('rhel') && !node.platform?('amazon')
|
||||
end
|
||||
|
||||
def javascript_binary
|
||||
# Debian and Ubuntu after 12.04 changed the binary name ಠ_ಠ.
|
||||
binary_name = node.value_for_platform(debian: {default: 'nodejs'}, ubuntu: {'12.04' => 'node', default: 'nodejs'}, default: 'node')
|
||||
::File.join('', 'usr', 'bin', binary_name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def install_javascript
|
||||
install_system_packages
|
||||
package %w{npm nodejs-legacy} if node.platform_family?('debian')
|
||||
end
|
||||
|
||||
def uninstall_javascript
|
||||
uninstall_system_packages
|
||||
package(%w{npm nodejs-legacy}) { action :purge } if node.platform_family?('debian')
|
||||
end
|
||||
|
||||
def system_package_candidates(version)
|
||||
# Boring :-(.
|
||||
%w{nodejs nodejs-legacy node}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'poise_javascript/resources/javascript_execute'
|
||||
require 'poise_javascript/resources/javascript_runtime'
|
||||
require 'poise_javascript/resources/node_package'
|
||||
require 'poise_javascript/resources/npm_install'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
# Chef resources and providers for poise-javascript.
|
||||
#
|
||||
# @since 1.0.0
|
||||
module Resources
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,83 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/mixin/which'
|
||||
require 'chef/provider/execute'
|
||||
require 'chef/resource/execute'
|
||||
require 'poise'
|
||||
|
||||
require 'poise_javascript/javascript_command_mixin'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module Resources
|
||||
# (see JavascriptExecute::Resource)
|
||||
# @since 1.0.0
|
||||
module JavascriptExecute
|
||||
# A `javascript_execute` resource to run Javascript scripts and commands.
|
||||
#
|
||||
# @provides javascript_execute
|
||||
# @action run
|
||||
# @example
|
||||
# javascript_execute 'myapp.js' do
|
||||
# user 'myuser'
|
||||
# end
|
||||
class Resource < Chef::Resource::Execute
|
||||
include PoiseJavascript::JavascriptCommandMixin
|
||||
provides(:javascript_execute)
|
||||
actions(:run)
|
||||
end
|
||||
|
||||
# The default provider for `javascript_execute`.
|
||||
#
|
||||
# @see Resource
|
||||
# @provides javascript_execute
|
||||
class Provider < Chef::Provider::Execute
|
||||
include Chef::Mixin::Which
|
||||
provides(:javascript_execute)
|
||||
|
||||
private
|
||||
|
||||
# Command to pass to shell_out.
|
||||
#
|
||||
# @return [String, Array<String>]
|
||||
def command
|
||||
if new_resource.command.is_a?(Array)
|
||||
[new_resource.javascript] + new_resource.command
|
||||
else
|
||||
"#{new_resource.javascript} #{new_resource.command}"
|
||||
end
|
||||
end
|
||||
|
||||
# Environment variables to pass to shell_out.
|
||||
#
|
||||
# @return [Hash]
|
||||
def environment
|
||||
if new_resource.parent_javascript
|
||||
environment = new_resource.parent_javascript.javascript_environment
|
||||
if new_resource.environment
|
||||
environment = environment.merge(new_resource.environment)
|
||||
end
|
||||
environment
|
||||
else
|
||||
new_resource.environment
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,85 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/resource'
|
||||
require 'poise'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module Resources
|
||||
# (see JavascriptRuntime::Resource)
|
||||
# @since 1.0.0
|
||||
module JavascriptRuntime
|
||||
# A `javascript_runtime` resource to manage Javascript installations.
|
||||
#
|
||||
# @provides javascript_runtime
|
||||
# @action install
|
||||
# @action uninstall
|
||||
# @example
|
||||
# javascript_runtime '2.7'
|
||||
class Resource < Chef::Resource
|
||||
include Poise(inversion: true, container: true)
|
||||
provides(:javascript_runtime)
|
||||
actions(:install, :uninstall)
|
||||
|
||||
# @!attribute version
|
||||
# Version of Javascript to install. This is generally a NodeJS version
|
||||
# but because of io.js there are shenanigans.
|
||||
# @return [String]
|
||||
# @example Install any version
|
||||
# javascript_runtime 'any' do
|
||||
# version ''
|
||||
# end
|
||||
attribute(:version, kind_of: String, name_attribute: true)
|
||||
|
||||
# The path to the `node` binary for this Javascript installation. This is
|
||||
# an output property.
|
||||
#
|
||||
# @return [String]
|
||||
# @example
|
||||
# execute "#{resources('javascript_runtime[nodejs]').javascript_binary} myapp.js"
|
||||
def javascript_binary
|
||||
provider_for_action(:javascript_binary).javascript_binary
|
||||
end
|
||||
|
||||
# The environment variables for this Javascript installation. This is an
|
||||
# output property.
|
||||
#
|
||||
# @return [Hash<String, String>]
|
||||
# @example
|
||||
# execute '/opt/myapp.js' do
|
||||
# environment resources('javascript_runtime[nodejs]').javascript_environment
|
||||
# end
|
||||
def javascript_environment
|
||||
provider_for_action(:javascript_environment).javascript_environment
|
||||
end
|
||||
|
||||
# The path to the `npm` binary for this Javascript installation. This is
|
||||
# an output property. Can raise an exception if NPM is not supported for
|
||||
# this runtime.
|
||||
#
|
||||
# @return [String]
|
||||
# @example
|
||||
# execute "#{resources('javascript_runtime[nodejs]').npm_binary} install"
|
||||
def npm_binary
|
||||
provider_for_action(:npm_binary).npm_binary
|
||||
end
|
||||
end
|
||||
|
||||
# Providers can be found under lib/poise_javascript/javascript_providers/
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,226 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/provider'
|
||||
require 'chef/resource'
|
||||
require 'poise'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module Resources
|
||||
# (see JavascriptRuntimeTest::Resource)
|
||||
# @since 1.0.0
|
||||
# @api private
|
||||
module JavascriptRuntimeTest
|
||||
# A `javascript_runtime_test` resource for integration testing of this
|
||||
# cookbook. This is an internal API and can change at any time.
|
||||
#
|
||||
# @provides javascript_runtime_test
|
||||
# @action run
|
||||
class Resource < Chef::Resource
|
||||
include Poise
|
||||
provides(:javascript_runtime_test)
|
||||
actions(:run)
|
||||
|
||||
attribute(:version, kind_of: String, name_attribute: true)
|
||||
attribute(:runtime_provider, kind_of: Symbol)
|
||||
attribute(:path, kind_of: String, default: lazy { default_path })
|
||||
attribute(:test_yo, equal_to: [true, false], default: true)
|
||||
|
||||
def default_path
|
||||
::File.join('', 'root', "javascript_test_#{name}")
|
||||
end
|
||||
end
|
||||
|
||||
# The default provider for `javascript_runtime_test`.
|
||||
#
|
||||
# @see Resource
|
||||
# @provides javascript_runtime_test
|
||||
class Provider < Chef::Provider
|
||||
include Poise
|
||||
provides(:javascript_runtime_test)
|
||||
|
||||
# The `run` action for the `javascript_runtime_test` resource.
|
||||
#
|
||||
# @return [void]
|
||||
def action_run
|
||||
notifying_block do
|
||||
# Top level directory for this test.
|
||||
directory new_resource.path
|
||||
|
||||
# Install and log the version.
|
||||
javascript_runtime new_resource.name do
|
||||
provider new_resource.runtime_provider if new_resource.runtime_provider
|
||||
version new_resource.version
|
||||
end
|
||||
test_version
|
||||
|
||||
# Create a package and test npm_install.
|
||||
pkg_path = ::File.join(new_resource.path, 'pkg')
|
||||
directory pkg_path
|
||||
file ::File.join(pkg_path, 'package.json') do
|
||||
content <<-EOH
|
||||
{
|
||||
"name": "mypkg",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \\"Error: no test specified\\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "4.13.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"handlebars": "4.0.2"
|
||||
}
|
||||
}
|
||||
EOH
|
||||
end
|
||||
npm_install pkg_path do
|
||||
notifies :create, sentinel_file('npm_install_one'), :immediately
|
||||
end
|
||||
npm_install pkg_path+'2' do
|
||||
path pkg_path
|
||||
notifies :create, sentinel_file('npm_install_two'), :immediately
|
||||
end
|
||||
test_require('express', pkg_path)
|
||||
test_require('handlebars', pkg_path)
|
||||
|
||||
# Test node_package.
|
||||
test1_path = ::File.join(new_resource.path, 'test1')
|
||||
directory test1_path
|
||||
node_package 'express' do
|
||||
path test1_path
|
||||
notifies :create, sentinel_file('test1_express_one'), :immediately
|
||||
end
|
||||
node_package 'express two' do
|
||||
package_name 'express'
|
||||
path test1_path
|
||||
notifies :create, sentinel_file('test1_express_two'), :immediately
|
||||
end
|
||||
node_package %w{gulp less} do
|
||||
path test1_path
|
||||
notifies :create, sentinel_file('test1_multi'), :immediately
|
||||
end
|
||||
node_package %w{express bower} do
|
||||
path test1_path
|
||||
notifies :create, sentinel_file('test1_multi_overlap'), :immediately
|
||||
end
|
||||
node_package 'bower' do
|
||||
path test1_path
|
||||
notifies :create, sentinel_file('test1_bower'), :immediately
|
||||
end
|
||||
node_package 'yo' do
|
||||
path test1_path
|
||||
version '1.4.5'
|
||||
end if new_resource.test_yo
|
||||
node_package 'forever' do
|
||||
path test1_path
|
||||
version '0.13.0'
|
||||
end
|
||||
test_require('express', test1_path, 'node_package_express')
|
||||
test_require('gulp', test1_path)
|
||||
test_require('less', test1_path)
|
||||
test_require('bower', test1_path)
|
||||
if new_resource.test_yo
|
||||
test_require('yo', test1_path)
|
||||
else
|
||||
file ::File.join(new_resource.path, 'no_yo')
|
||||
end
|
||||
test_require('forever', test1_path)
|
||||
|
||||
# Check we don't get cross talk between paths.
|
||||
test2_path = ::File.join(new_resource.path, 'test2')
|
||||
directory test2_path
|
||||
node_package 'express' do
|
||||
path test2_path
|
||||
notifies :create, sentinel_file('test2_express'), :immediately
|
||||
end
|
||||
|
||||
# Test global installs.
|
||||
node_package 'grunt-cli' do
|
||||
notifies :create, sentinel_file('grunt_one'), :immediately
|
||||
end
|
||||
node_package 'grunt-cli two' do
|
||||
package_name 'grunt-cli'
|
||||
notifies :create, sentinel_file('grunt_two'), :immediately
|
||||
end
|
||||
test_require('grunt-cli', new_resource.path)
|
||||
javascript_execute 'grunt-cli --version' do
|
||||
command lazy {
|
||||
# Check local/bin first and then just bin/.
|
||||
grunt_path = ::File.expand_path('../../local/bin/grunt', javascript)
|
||||
grunt_path = ::File.expand_path('../grunt', javascript) unless ::File.exist?(grunt_path)
|
||||
"#{grunt_path} --version > #{::File.join(new_resource.path, 'grunt_version')}"
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def sentinel_file(name)
|
||||
file ::File.join(new_resource.path, "sentinel_#{name}") do
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_version(javascript: new_resource.name)
|
||||
# Only queue up this resource once, the ivar is just for tracking.
|
||||
@javascript_version_test ||= file ::File.join(new_resource.path, 'javascript_version.js') do
|
||||
user 'root'
|
||||
group 'root'
|
||||
mode '644'
|
||||
content <<-EOH
|
||||
var fs = require('fs');
|
||||
fs.writeFileSync(process.argv[2], process.version);
|
||||
EOH
|
||||
end
|
||||
|
||||
javascript_execute "#{@javascript_version_test.path} #{::File.join(new_resource.path, 'version')}" do
|
||||
javascript javascript if javascript
|
||||
end
|
||||
end
|
||||
|
||||
def test_require(name, cwd, path=name, javascript: new_resource.name)
|
||||
javascript_require_test = file ::File.join(cwd, 'javascript_require.js') do
|
||||
user 'root'
|
||||
group 'root'
|
||||
mode '644'
|
||||
content <<-EOH
|
||||
var fs = require('fs');
|
||||
try {
|
||||
var version = require(process.argv[2] + '/package.json').version;
|
||||
fs.writeFileSync(process.argv[3], version);
|
||||
} catch(e) {
|
||||
}
|
||||
EOH
|
||||
end
|
||||
|
||||
javascript_execute "#{javascript_require_test.path} #{name} #{::File.join(new_resource.path, "require_#{path}")}" do
|
||||
javascript javascript if javascript
|
||||
cwd cwd
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,254 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/json_compat'
|
||||
require 'chef/provider/package'
|
||||
require 'chef/resource/package'
|
||||
require 'poise'
|
||||
|
||||
require 'poise_javascript/error'
|
||||
require 'poise_javascript/javascript_command_mixin'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module Resources
|
||||
# (see NodePackage::Resource)
|
||||
# @since 1.0.0
|
||||
module NodePackage
|
||||
# A `node_package` resource to manage Node.js packages using npm.
|
||||
#
|
||||
# @provides node_package
|
||||
# @action install
|
||||
# @action upgrade
|
||||
# @action uninstall
|
||||
# @example
|
||||
# node_package 'express' do
|
||||
# javascript '0.10'
|
||||
# version '1.8.3'
|
||||
# end
|
||||
class Resource < Chef::Resource::Package
|
||||
include PoiseJavascript::JavascriptCommandMixin
|
||||
provides(:node_package)
|
||||
# Manually create matchers because #actions is unreliable.
|
||||
%i{install upgrade remove}.each do |action|
|
||||
Poise::Helpers::ChefspecMatchers.create_matcher(:node_package, action)
|
||||
end
|
||||
|
||||
# @!attribute group
|
||||
# System group to install the package.
|
||||
# @return [String, Integer, nil]
|
||||
attribute(:group, kind_of: [String, Integer, NilClass])
|
||||
# @!attribute path
|
||||
# Path to install the package in to. If unset install using --global.
|
||||
# @return [String, nil, false]
|
||||
attribute(:path, kind_of: [String, NilClass, FalseClass])
|
||||
# @!attribute unsafe_perm
|
||||
# Enable --unsafe-perm.
|
||||
# @return [Boolean, nil]
|
||||
attribute(:unsafe_perm, equal_to: [true, false, nil], default: true)
|
||||
# @!attribute user
|
||||
# System user to install the package.
|
||||
# @return [String, Integer, nil]
|
||||
attribute(:user, kind_of: [String, Integer, NilClass])
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
# For older Chef.
|
||||
@resource_name = :node_package
|
||||
# We don't have these actions.
|
||||
@allowed_actions.delete(:purge)
|
||||
@allowed_actions.delete(:reconfig)
|
||||
end
|
||||
|
||||
# Upstream attribute we don't support. Sets are an error and gets always
|
||||
# return nil.
|
||||
#
|
||||
# @api private
|
||||
# @param arg [Object] Ignored
|
||||
# @return [nil]
|
||||
def response_file(arg=nil)
|
||||
raise NoMethodError if arg
|
||||
end
|
||||
|
||||
# (see #response_file)
|
||||
def response_file_variables(arg=nil)
|
||||
raise NoMethodError if arg && arg != {}
|
||||
end
|
||||
end
|
||||
|
||||
# The default provider for the `node_package` resource.
|
||||
#
|
||||
# @see Resource
|
||||
class Provider < Chef::Provider::Package
|
||||
include PoiseJavascript::JavascriptCommandMixin
|
||||
provides(:node_package)
|
||||
|
||||
# Load current and candidate versions for all needed packages.
|
||||
#
|
||||
# @api private
|
||||
# @return [Chef::Resource]
|
||||
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
|
||||
|
||||
# Populate current and candidate versions for all needed packages.
|
||||
#
|
||||
# @api private
|
||||
# @param resource [PoiseJavascript::Resources::NodePackage::Resource]
|
||||
# Resource to load for.
|
||||
# @return [void]
|
||||
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', returns: [0, 1]) || {}
|
||||
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]
|
||||
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
|
||||
|
||||
# Upgrade and install are the same for NPM.
|
||||
alias_method :upgrade_package, :install_package
|
||||
|
||||
# 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]
|
||||
def remove_package(name, version)
|
||||
npm_shell_out!('uninstall', [name].flatten, parse_json: false)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# 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]
|
||||
def npm_shell_out!(subcmd, args=[], parse_json: true, **kwargs)
|
||||
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}, **kwargs)
|
||||
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]
|
||||
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]
|
||||
def npm_version?(req)
|
||||
Gem::Requirement.new(req).satisfied_by?(npm_version)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,98 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
require 'chef/provider'
|
||||
require 'chef/resource'
|
||||
require 'poise'
|
||||
|
||||
require 'poise_javascript/javascript_command_mixin'
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
module Resources
|
||||
# (see NpmInstall::Resource)
|
||||
# @since 1.0.0
|
||||
module NpmInstall
|
||||
# A `npm_install` resource to install NPM packages based on a package.json.
|
||||
#
|
||||
# @provides npm_install
|
||||
# @action install
|
||||
# @example
|
||||
# npm_install '/opt/myapp'
|
||||
class Resource < Chef::Resource
|
||||
include PoiseJavascript::JavascriptCommandMixin
|
||||
provides(:npm_install)
|
||||
actions(:install)
|
||||
|
||||
# @!attribute path
|
||||
# Directory to run `npm install` from.
|
||||
# @return [String]
|
||||
attribute(:path, kind_of: String, name_attribute: true)
|
||||
# @!attribute group
|
||||
# System group to install the packages.
|
||||
# @return [String, Integer, nil]
|
||||
attribute(:group, kind_of: [String, Integer, NilClass])
|
||||
# @!attribute production
|
||||
# Enable production install mode.
|
||||
# @return [Boolean]
|
||||
attribute(:production, equal_to: [true, false], default: true)
|
||||
# @!attribute timeout
|
||||
# Command execution timeout.
|
||||
# @return [Integer]
|
||||
attribute(:timeout, kind_of: Integer, default: 900)
|
||||
# @!attribute unsafe_perm
|
||||
# Enable --unsafe-perm.
|
||||
# @return [Boolean, nil]
|
||||
attribute(:unsafe_perm, equal_to: [true, false, nil], default: true)
|
||||
# @!attribute user
|
||||
# System user to install the packages.
|
||||
# @return [String, Integer, nil]
|
||||
attribute(:user, kind_of: [String, Integer, NilClass])
|
||||
end
|
||||
|
||||
# The default provider for `npm_install`.
|
||||
#
|
||||
# @see Resource
|
||||
# @provides npm_install
|
||||
class Provider < Chef::Provider
|
||||
include Poise
|
||||
include PoiseJavascript::JavascriptCommandMixin
|
||||
provides(:npm_install)
|
||||
|
||||
# The `install` action for the `npm_install` resource.
|
||||
#
|
||||
# @return [void]
|
||||
def action_install
|
||||
cmd = [new_resource.npm_binary, 'install', '--no-audit']
|
||||
cmd << '--production' if new_resource.production
|
||||
# Set --unsafe-perm unless the property is nil.
|
||||
unless new_resource.unsafe_perm.nil?
|
||||
cmd << '--unsafe-perm'
|
||||
cmd << new_resource.unsafe_perm.to_s
|
||||
end
|
||||
# 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)
|
||||
output = javascript_shell_out!(cmd, cwd: new_resource.path, user: new_resource.user, group: new_resource.group, environment: {'PATH' => new_path}, timeout: new_resource.timeout).stdout
|
||||
unless output.strip.empty? || output.include?('up to date')
|
||||
# Any output means it did something for old NPM, "up to date" for newer.
|
||||
new_resource.updated_by_last_action(true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Copyright 2015-2017, Noah Kantrowitz
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
|
||||
module PoiseJavascript
|
||||
VERSION = '1.2.1.pre'
|
||||
end
|
||||
Reference in New Issue
Block a user