berkshelf_ext 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +2 -0
- data/README.md +42 -0
- data/berkshelf_ext.gemspec +15 -0
- data/bin/berks_ext +15 -0
- data/lib/berkshelf.rb +13 -0
- data/lib/berkshelf_ext.rb +1 -0
- data/lib/berkshelf_ext/all.rb +11 -0
- data/lib/berkshelf_ext/berksfile_loader_context.rb +53 -0
- data/lib/berkshelf_ext/dependency_chains.rb +65 -0
- data/lib/berkshelf_ext/nested_berksfiles.rb +82 -0
- data/lib/berkshelf_ext/version.rb +7 -0
- metadata +74 -0
data/CHANGELOG.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Berkshelf Ext
|
2
|
+
|
3
|
+
Berkshelf extensions to add features to berkshelf not
|
4
|
+
accepted upstream.
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
### Via Bundler
|
9
|
+
|
10
|
+
If using via `bundler`, just add an entry in the Gemfile:
|
11
|
+
|
12
|
+
`gem 'berkshelf_ext'`
|
13
|
+
|
14
|
+
and it will auto inject itself.
|
15
|
+
|
16
|
+
### Direct
|
17
|
+
|
18
|
+
Since bundler does some special loading that rubygems proper
|
19
|
+
does not, we can't auto-inject ourselves in. Instead, just
|
20
|
+
call the custom executable:
|
21
|
+
|
22
|
+
`berks_ext`
|
23
|
+
|
24
|
+
Which will add the extensions to berkshelf, and then initialize
|
25
|
+
it as usual.
|
26
|
+
|
27
|
+
## Current extensions
|
28
|
+
|
29
|
+
* Resolution via nested berksfiles (nested_berksfiles)
|
30
|
+
* Proper berksfile path when loading berksfiles (berksfile_loader_context)
|
31
|
+
* Proper dependency resolution (dependency_chains)
|
32
|
+
|
33
|
+
## Prevent extension loading
|
34
|
+
|
35
|
+
You can explicitly define what is allowed or not allowed to load via
|
36
|
+
environment variables
|
37
|
+
|
38
|
+
* `BERKSHELF_EXT_EXCEPT="nested_berksfiles"`
|
39
|
+
* `BERKSHELF_EXT_ONLY="nested_berksfiles,berksfile_loader_context"`
|
40
|
+
|
41
|
+
# Info
|
42
|
+
* Repository: https://github.com/chrisroberts/berkshelf_ext
|
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__)) + '/lib/'
|
2
|
+
require 'berkshelf_ext/version'
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'berkshelf_ext'
|
5
|
+
s.version = BerkshelfExt::VERSION.version
|
6
|
+
s.summary = 'Extensions for Berkshelf'
|
7
|
+
s.author = 'Chris Roberts'
|
8
|
+
s.email = 'chrisroberts.code@gmail.com'
|
9
|
+
s.homepage = 'http://github.com/chrisroberts/berkshelf_ext'
|
10
|
+
s.description = 'Extenstions for berkshelf'
|
11
|
+
s.require_path = 'lib'
|
12
|
+
s.executables = %w(berks_ext)
|
13
|
+
s.add_dependency 'berkshelf', BerkshelfExt::BERKSHELF_CONSTRAINT
|
14
|
+
s.files = Dir['**/*']
|
15
|
+
end
|
data/bin/berks_ext
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'berkshelf_ext/all'
|
4
|
+
|
5
|
+
begin
|
6
|
+
Berkshelf::Cli.start
|
7
|
+
rescue Berkshelf::BerkshelfError => e
|
8
|
+
Berkshelf.ui.error e
|
9
|
+
Berkshelf.ui.error "\t" + e.backtrace.join("\n\t") if ENV['BERKSHELF_DEBUG']
|
10
|
+
exit e.status_code
|
11
|
+
rescue Ridley::Errors::RidleyError => e
|
12
|
+
Berkshelf.ui.error "#{e.class} #{e}"
|
13
|
+
Berkshelf.ui.error "\t" + e.backtrace.join("\n\t") if ENV['BERKSHELF_DEBUG']
|
14
|
+
exit 47
|
15
|
+
end
|
data/lib/berkshelf.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'berkshelf_ext/version'
|
2
|
+
|
3
|
+
berk_spec = Gem::Specification.find_by_name('berkshelf', BerkshelfExt::BERKSHELF_CONSTRAINT)
|
4
|
+
|
5
|
+
unless(berk_spec)
|
6
|
+
raise "Failed to locate acceptable berkshelf version. (Constraint: #{BerkshelfExt::BERKSHELF_CONSTRAINT})"
|
7
|
+
end
|
8
|
+
|
9
|
+
berk_spec.activate_dependencies
|
10
|
+
berk_spec.activate
|
11
|
+
require File.join(berk_spec.full_gem_path, 'lib/berkshelf.rb')
|
12
|
+
|
13
|
+
require 'berkshelf_ext/all'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'berkshelf_ext/version'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'berkshelf'
|
2
|
+
|
3
|
+
Dir.glob(File.join(File.dirname(__FILE__), '*.rb')).each do |ext_file|
|
4
|
+
if(ENV['BERKSHELF_EXT_EXCEPT'])
|
5
|
+
next if ENV['BERKSHELF_EXT_EXCEPT'].split(',').include?(File.basename(ext_file).sub('.rb', ''))
|
6
|
+
end
|
7
|
+
if(ENV['BERKSHELF_EXT_ONLY'])
|
8
|
+
next unless ENV['BERKSHELF_EXT_ONLY'].split(',').include?(File.basename(ext_file).sub('.rb', ''))
|
9
|
+
end
|
10
|
+
require ext_file
|
11
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Berkshelf
|
2
|
+
module BerksfileLoaderContext
|
3
|
+
module Berksfile
|
4
|
+
def self.included(klass)
|
5
|
+
klass.send(:include, InstanceMethods)
|
6
|
+
klass.send(:extend, ClassMethods)
|
7
|
+
klass.class_eval do
|
8
|
+
alias_method :non_berksfile_loader_context_load, :load
|
9
|
+
alias_method :load, :berksfile_loader_context_load
|
10
|
+
alias_method :non_berksfile_loader_context_cookbook, :cookbook
|
11
|
+
alias_method :cookbook, :berksfile_loader_context_cookbook
|
12
|
+
class << self
|
13
|
+
alias_method :non_berksfile_loader_context_from_file, :from_file
|
14
|
+
alias_method :from_file, :berksfile_loader_context_from_file
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
module InstanceMethods
|
19
|
+
def berksfile_loader_context_load(content, path='')
|
20
|
+
initial_path = Dir.pwd
|
21
|
+
begin
|
22
|
+
Dir.chdir(File.dirname(path))
|
23
|
+
instance_eval(content, File.expand_path(path), 1)
|
24
|
+
rescue => e
|
25
|
+
raise BerksfileReadError.new(e), "An error occurred while reading the Berksfile: #{e.to_s}"
|
26
|
+
ensure
|
27
|
+
Dir.chdir(initial_path)
|
28
|
+
end
|
29
|
+
self
|
30
|
+
end
|
31
|
+
def berksfile_loader_context_cookbook(*args)
|
32
|
+
if(args.last.is_a?(Hash) && args.last[:path])
|
33
|
+
args.last[:path] = File.expand_path(args.last[:path])
|
34
|
+
end
|
35
|
+
non_berksfile_loader_context_cookbook(*args)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
module ClassMethods
|
39
|
+
def berksfile_loader_context_from_file(file)
|
40
|
+
begin
|
41
|
+
object = new(file)
|
42
|
+
content = File.read(file)
|
43
|
+
object.load(content, file.to_s)
|
44
|
+
rescue Errno::ENOENT => e
|
45
|
+
raise BerksfileNotFound, "No Berksfile or Berksfile.lock found at: #{file}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
Berkshelf::Berksfile.send(:include, Berkshelf::BerksfileLoaderContext::Berksfile)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module BerkshelfExt
|
2
|
+
module DependencyChains
|
3
|
+
module Resolver
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def included(klass)
|
7
|
+
klass.class_eval do
|
8
|
+
alias_method :non_dependency_chains_resolve, :resolve
|
9
|
+
alias_method :resolve, :dependency_chains_resolve
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def defined_artifacts
|
15
|
+
Hash[*(
|
16
|
+
graph.artifacts.map do |art|
|
17
|
+
[art.name, art]
|
18
|
+
end
|
19
|
+
).flatten]
|
20
|
+
end
|
21
|
+
|
22
|
+
def chain_dependencies!
|
23
|
+
defined_artifacts.each do |name, artifact|
|
24
|
+
@sources[name].cached_cookbook.dependencies.each do |dep|
|
25
|
+
dep << ">= 0.0.0" unless dep.size > 1
|
26
|
+
artifact.depends(dep.first, dep.last)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def dependency_chains_resolve(demands = nil)
|
32
|
+
demands = Array(demands) unless demands.is_a?(Array)
|
33
|
+
if(demands.empty?)
|
34
|
+
demands = [].tap do |l_demands|
|
35
|
+
graph.artifacts.each do |artifact|
|
36
|
+
l_demands << [artifact.name, artifact.version]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
unless(@skip_dependencies)
|
41
|
+
chain_dependencies!
|
42
|
+
end
|
43
|
+
# since we only get an error if the graph does not contain a
|
44
|
+
# solution and not the dependency that caused the failure, run
|
45
|
+
# each dependency through the graph individually so we can
|
46
|
+
# provide a useful error string
|
47
|
+
demands.each do |demand|
|
48
|
+
begin
|
49
|
+
solution = Solve.it!(graph, [demand])
|
50
|
+
rescue Solve::Errors::NoSolutionError
|
51
|
+
raise Berkshelf::NoSolution.new("Failed to resolve dependencies for: #{demand.join(': ')}")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
solution = Solve.it!(graph, demands)
|
55
|
+
[].tap do |cached_cookbooks|
|
56
|
+
solution.each do |name, version|
|
57
|
+
cached_cookbooks << get_source(name).cached_cookbook
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
Berkshelf::Resolver.send(:include, BerkshelfExt::DependencyChains::Resolver)
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module BerkshelfExt
|
2
|
+
module NestedBerksfiles
|
3
|
+
module Cli
|
4
|
+
class << self
|
5
|
+
def included(klass)
|
6
|
+
klass.tasks['upload'].options[:nested_berksfiles] = Thor::Option.new(
|
7
|
+
'nested_berksfiles', :type => :boolean, :default => false,
|
8
|
+
:desc => 'Use Berksfiles found within cookbooks specifed in Berksfile'
|
9
|
+
)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Berksfile
|
15
|
+
class << self
|
16
|
+
def included(klass)
|
17
|
+
klass.class_eval do
|
18
|
+
alias_method :non_nested_berksfiles_resolver, :resolver
|
19
|
+
alias_method :resolver, :nested_berksfiles_resolver
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def nested_berksfiles_resolver(options={})
|
25
|
+
Berkshelf::Resolver.new(
|
26
|
+
self.downloader,
|
27
|
+
sources: sources(options),
|
28
|
+
skip_dependencies: options[:skip_dependencies],
|
29
|
+
nested_berksfiles: options[:nested_berksfiles]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Resolver
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def included(klass)
|
38
|
+
klass.class_eval do
|
39
|
+
alias_method :non_nested_berksfiles_initialize, :initialize
|
40
|
+
alias_method :initialize, :nested_berksfiles_initialize
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def nested_berksfiles_initialize(downloader, options={})
|
46
|
+
skip_deps = options[:skip_dependencies]
|
47
|
+
options[:skip_dependencies] = true
|
48
|
+
non_nested_berksfiles_initialize(downloader, options)
|
49
|
+
@skip_dependencies = options[:skip_dependencies] = skip_deps
|
50
|
+
if(options[:nested_berksfiles])
|
51
|
+
process_nested_berksfiles(options[:sources])
|
52
|
+
end
|
53
|
+
unless(options[:skip_dependencies])
|
54
|
+
@sources.values.each do |source|
|
55
|
+
add_source_dependencies(source)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def process_nested_berksfiles(srcs)
|
61
|
+
srcs.map(&:name).each do |name|
|
62
|
+
berks_path = File.join(@sources[name].cached_cookbook.path, 'Berksfile')
|
63
|
+
if(File.exists?(berks_path))
|
64
|
+
berksfile = Berkshelf::Berksfile.from_file(berks_path)
|
65
|
+
new_sources = berksfile.sources.delete_if do |new_src|
|
66
|
+
@sources.has_key?(new_src.name)
|
67
|
+
end
|
68
|
+
new_sources.each do |source|
|
69
|
+
add_source(source, false)
|
70
|
+
end
|
71
|
+
process_nested_berksfiles(new_sources)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
Berkshelf::Cli.send(:include, BerkshelfExt::NestedBerksfiles::Cli)
|
81
|
+
Berkshelf::Berksfile.send(:include, BerkshelfExt::NestedBerksfiles::Berksfile)
|
82
|
+
Berkshelf::Resolver.send(:include, BerkshelfExt::NestedBerksfiles::Resolver)
|
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: berkshelf_ext
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chris Roberts
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: berkshelf
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.3.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.3.1
|
30
|
+
description: Extenstions for berkshelf
|
31
|
+
email: chrisroberts.code@gmail.com
|
32
|
+
executables:
|
33
|
+
- berks_ext
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- lib/berkshelf.rb
|
38
|
+
- lib/berkshelf_ext/all.rb
|
39
|
+
- lib/berkshelf_ext/nested_berksfiles.rb
|
40
|
+
- lib/berkshelf_ext/version.rb
|
41
|
+
- lib/berkshelf_ext/dependency_chains.rb
|
42
|
+
- lib/berkshelf_ext/berksfile_loader_context.rb
|
43
|
+
- lib/berkshelf_ext.rb
|
44
|
+
- README.md
|
45
|
+
- berkshelf_ext.gemspec
|
46
|
+
- bin/berks_ext
|
47
|
+
- berkshelf_ext-1.0.0.gem
|
48
|
+
- CHANGELOG.md
|
49
|
+
homepage: http://github.com/chrisroberts/berkshelf_ext
|
50
|
+
licenses: []
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.8.24
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: Extensions for Berkshelf
|
73
|
+
test_files: []
|
74
|
+
has_rdoc:
|