berkshelf_ext 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|