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 ADDED
@@ -0,0 +1,2 @@
1
+ ## v0.1.0
2
+ * Initial release
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)
@@ -0,0 +1,7 @@
1
+ module BerkshelfExt
2
+ class Version < Gem::Version
3
+ end
4
+
5
+ VERSION = Version.new('1.0.0')
6
+ BERKSHELF_CONSTRAINT = '~> 1.3.1'
7
+ end
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: