librarian 0.0.9 → 0.0.10

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.
Files changed (64) hide show
  1. data/CHANGELOG.md +4 -0
  2. data/lib/librarian.rb +5 -178
  3. data/lib/librarian/action.rb +5 -0
  4. data/lib/librarian/action/base.rb +22 -0
  5. data/lib/librarian/action/clean.rb +56 -0
  6. data/lib/librarian/action/ensure.rb +24 -0
  7. data/lib/librarian/action/install.rb +101 -0
  8. data/lib/librarian/action/resolve.rb +81 -0
  9. data/lib/librarian/action/update.rb +76 -0
  10. data/lib/librarian/chef/cli.rb +7 -2
  11. data/lib/librarian/chef/dsl.rb +0 -3
  12. data/lib/librarian/chef/environment.rb +19 -0
  13. data/lib/librarian/chef/extension.rb +1 -16
  14. data/lib/librarian/chef/integration/knife.rb +9 -16
  15. data/lib/librarian/chef/source/git.rb +0 -2
  16. data/lib/librarian/chef/source/local.rb +1 -74
  17. data/lib/librarian/chef/source/local/manifest.rb +82 -0
  18. data/lib/librarian/chef/source/path.rb +0 -2
  19. data/lib/librarian/chef/source/site.rb +9 -89
  20. data/lib/librarian/chef/source/site/manifest.rb +94 -0
  21. data/lib/librarian/cli.rb +56 -17
  22. data/lib/librarian/dependency.rb +2 -2
  23. data/lib/librarian/dsl.rb +15 -5
  24. data/lib/librarian/dsl/receiver.rb +2 -0
  25. data/lib/librarian/dsl/target.rb +13 -1
  26. data/lib/librarian/environment.rb +94 -0
  27. data/lib/librarian/error.rb +4 -0
  28. data/lib/librarian/helpers/debug.rb +6 -6
  29. data/lib/librarian/lockfile.rb +7 -5
  30. data/lib/librarian/lockfile/compiler.rb +5 -4
  31. data/lib/librarian/lockfile/parser.rb +6 -5
  32. data/lib/librarian/manifest.rb +2 -2
  33. data/lib/librarian/mock/cli.rb +6 -1
  34. data/lib/librarian/mock/dsl.rb +0 -3
  35. data/lib/librarian/mock/environment.rb +24 -0
  36. data/lib/librarian/mock/extension.rb +1 -20
  37. data/lib/librarian/mock/source/mock.rb +7 -7
  38. data/lib/librarian/mock/source/mock/registry.rb +16 -12
  39. data/lib/librarian/resolver.rb +5 -116
  40. data/lib/librarian/resolver/implementation.rb +117 -0
  41. data/lib/librarian/source/git.rb +8 -7
  42. data/lib/librarian/source/git/repository.rb +7 -5
  43. data/lib/librarian/source/local.rb +1 -1
  44. data/lib/librarian/source/path.rb +7 -6
  45. data/lib/librarian/spec_change_set.rb +6 -5
  46. data/lib/librarian/specfile.rb +10 -4
  47. data/lib/librarian/version.rb +1 -1
  48. data/librarian.gemspec +1 -0
  49. data/spec/functional/chef/source/git_spec.rb +177 -89
  50. data/spec/functional/chef/source/site_spec.rb +111 -52
  51. data/spec/unit/action/base_spec.rb +18 -0
  52. data/spec/unit/action/clean_spec.rb +133 -0
  53. data/spec/unit/action/ensure_spec.rb +37 -0
  54. data/spec/unit/action/install_spec.rb +113 -0
  55. data/spec/unit/dsl_spec.rb +15 -13
  56. data/spec/unit/environment_spec.rb +9 -0
  57. data/spec/unit/lockfile_spec.rb +15 -4
  58. data/spec/unit/mock/source/mock.rb +22 -0
  59. data/spec/unit/resolver_spec.rb +24 -24
  60. data/spec/unit/spec_change_set_spec.rb +29 -25
  61. metadata +47 -19
  62. data/lib/librarian/chef/particularity.rb +0 -9
  63. data/lib/librarian/mock/particularity.rb +0 -9
  64. data/lib/librarian/particularity.rb +0 -7
@@ -0,0 +1,94 @@
1
+ require "fileutils"
2
+
3
+ require "json"
4
+
5
+ require "librarian/dependency"
6
+ require 'librarian/chef/manifest'
7
+
8
+ module Librarian
9
+ module Chef
10
+ module Source
11
+ class Site
12
+ class Manifest < Manifest
13
+
14
+ attr_reader :version_uri
15
+ attr_reader :install_path
16
+
17
+ def initialize(source, name, version_uri = nil)
18
+ super(source, name)
19
+ @version_uri = version_uri
20
+
21
+ @cache_path = nil
22
+ @metadata_cache_path = nil
23
+ @package_cache_path = nil
24
+ @install_path = environment.install_path.join(name)
25
+
26
+ @version_metadata = nil
27
+ @version_manifest = nil
28
+ end
29
+
30
+ def fetch_version!
31
+ version_metadata['version']
32
+ end
33
+
34
+ def fetch_dependencies!
35
+ version_manifest['dependencies'].map{|k, v| Dependency.new(k, v, nil)}
36
+ end
37
+
38
+ def version_uri
39
+ @version_uri ||= begin
40
+ source.cache!([self])
41
+ source.manifests(self).find{|m| m.version == version}.version_uri
42
+ end
43
+ end
44
+
45
+ def version_uri=(version_uri)
46
+ @version_uri = version_uri
47
+ end
48
+
49
+ def cache_path
50
+ @cache_path ||= source.version_cache_path(self, version_uri)
51
+ end
52
+ def metadata_cache_path
53
+ @metadata_cache_path ||= cache_path.join('version.json')
54
+ end
55
+ def package_cache_path
56
+ @package_cache_path ||= cache_path.join('package')
57
+ end
58
+
59
+ def version_metadata
60
+ @version_metadata ||= fetch_version_metadata!
61
+ end
62
+
63
+ def fetch_version_metadata!
64
+ source.cache_version_metadata!(self, version_uri)
65
+ JSON.parse(metadata_cache_path.read)
66
+ end
67
+
68
+ def version_manifest
69
+ @version_manifest ||= fetch_version_manifest!
70
+ end
71
+
72
+ def fetch_version_manifest!
73
+ source.cache_version_package!(self, version_uri, version_metadata['file'])
74
+ manifest_path = manifest_path(package_cache_path)
75
+ read_manifest(name, manifest_path)
76
+ end
77
+
78
+ def install!
79
+ debug { "Installing #{self}" }
80
+ version_manifest # make sure it's cached
81
+ if install_path.exist?
82
+ debug { "Deleting #{relative_path_to(install_path)}" }
83
+ install_path.rmtree
84
+ end
85
+ package_cache_path = source.version_package_cache_path(self, version_uri)
86
+ debug { "Copying #{relative_path_to(package_cache_path)} to #{relative_path_to(install_path)}" }
87
+ FileUtils.cp_r(package_cache_path, install_path)
88
+ end
89
+
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
data/lib/librarian/cli.rb CHANGED
@@ -1,24 +1,36 @@
1
1
  require 'thor'
2
2
  require 'thor/actions'
3
+
3
4
  require 'librarian'
5
+ require 'librarian/error'
6
+ require 'librarian/action'
7
+ require "librarian/ui"
4
8
 
5
9
  module Librarian
6
10
  class Cli < Thor
7
11
 
8
12
  include Thor::Actions
13
+
14
+ module Particularity
15
+ def root_module
16
+ nil
17
+ end
18
+ end
19
+
9
20
  include Particularity
10
21
  extend Particularity
11
22
 
12
23
  class << self
13
24
  def bin!
14
25
  begin
26
+ environment = root_module.environment
15
27
  start
16
28
  rescue Librarian::Error => e
17
- root_module.ui.error e.message
18
- root_module.ui.debug e.backtrace.join("\n")
29
+ environment.ui.error e.message
30
+ environment.ui.debug e.backtrace.join("\n")
19
31
  exit (e.respond_to?(:status_code) ? e.status_code : 1)
20
32
  rescue Interrupt => e
21
- root_module.ui.error "\nQuitting..."
33
+ environment.ui.error "\nQuitting..."
22
34
  exit 1
23
35
  end
24
36
  end
@@ -27,9 +39,9 @@ module Librarian
27
39
  def initialize(*)
28
40
  super
29
41
  the_shell = (options["no-color"] ? Thor::Shell::Basic.new : shell)
30
- root_module.ui = UI::Shell.new(the_shell)
31
- root_module.ui.debug! if options["verbose"]
32
- root_module.ui.debug_line_numbers! if options["verbose"] && options["line-numbers"]
42
+ environment.ui = UI::Shell.new(the_shell)
43
+ environment.ui.debug! if options["verbose"]
44
+ environment.ui.debug_line_numbers! if options["verbose"] && options["line-numbers"]
33
45
  end
34
46
 
35
47
  desc "version", "Displays the version."
@@ -41,8 +53,8 @@ module Librarian
41
53
  method_option "verbose"
42
54
  method_option "line-numbers"
43
55
  def clean
44
- root_module.ensure!
45
- root_module.clean!
56
+ ensure!
57
+ clean!
46
58
  end
47
59
 
48
60
  desc "install", "Installs all of the dependencies you specify."
@@ -50,9 +62,10 @@ module Librarian
50
62
  method_option "line-numbers"
51
63
  method_option "clean"
52
64
  def install
53
- root_module.ensure!
54
- root_module.clean! if options["clean"]
55
- root_module.install!
65
+ ensure!
66
+ clean! if options["clean"]
67
+ resolve!
68
+ install!
56
69
  end
57
70
 
58
71
  desc "resolve", "Resolves the dependencies you specify."
@@ -60,20 +73,20 @@ module Librarian
60
73
  method_option "line-numbers"
61
74
  method_option "clean"
62
75
  def resolve
63
- root_module.ensure!
64
- root_module.clean! if options["clean"]
65
- root_module.resolve!
76
+ ensure!
77
+ clean! if options["clean"]
78
+ resolve!
66
79
  end
67
80
 
68
81
  desc "update", "Updates the dependencies you specify."
69
82
  method_option "verbose"
70
83
  method_option "line-numbers"
71
84
  def update(*names)
72
- root_module.ensure!
85
+ ensure!
73
86
  if names.empty?
74
- root_module.resolve!(:force => true)
87
+ resolve!(:force => true)
75
88
  else
76
- root_module.update!(names)
89
+ update!(:names => names)
77
90
  end
78
91
  end
79
92
 
@@ -82,5 +95,31 @@ module Librarian
82
95
  puts "Nothing to do."
83
96
  end
84
97
 
98
+ private
99
+
100
+ def environment
101
+ root_module.environment
102
+ end
103
+
104
+ def ensure!(options = { })
105
+ Action::Ensure.new(environment, options).run
106
+ end
107
+
108
+ def clean!(options = { })
109
+ Action::Clean.new(environment, options).run
110
+ end
111
+
112
+ def install!(options = { })
113
+ Action::Install.new(environment, options).run
114
+ end
115
+
116
+ def resolve!(options = { })
117
+ Action::Resolve.new(environment, options).run
118
+ end
119
+
120
+ def update!(options = { })
121
+ Action::Update.new(environment, options).run
122
+ end
123
+
85
124
  end
86
125
  end
@@ -46,8 +46,8 @@ module Librarian
46
46
 
47
47
  private
48
48
 
49
- def root_module
50
- source.root_module
49
+ def environment
50
+ source.environment
51
51
  end
52
52
 
53
53
  end
data/lib/librarian/dsl.rb CHANGED
@@ -2,21 +2,22 @@ require 'librarian/dependency'
2
2
  require 'librarian/dsl/receiver'
3
3
  require 'librarian/dsl/target'
4
4
  require 'librarian/helpers/debug'
5
- require 'librarian/particularity'
6
5
 
7
6
  module Librarian
8
7
  class Dsl
9
8
 
10
- include Particularity
11
9
  include Helpers::Debug
12
10
 
13
11
  class Error < Exception
14
12
  end
15
13
 
14
+ attr_accessor :environment
15
+ private :environment=
16
+
16
17
  class << self
17
18
 
18
- def run(specfile = nil, precache_sources = [], &block)
19
- new.run(specfile, precache_sources, &block)
19
+ def run(environment, specfile = nil, precache_sources = [], &block)
20
+ new(environment).run(specfile, precache_sources, &block)
20
21
  end
21
22
 
22
23
  private
@@ -65,6 +66,10 @@ module Librarian
65
66
 
66
67
  delegate_to_class :dependency_name, :dependency_type, :source_types, :source_shortcuts
67
68
 
69
+ def initialize(environment)
70
+ self.environment = environment
71
+ end
72
+
68
73
  def run(specfile = nil, sources = [])
69
74
  Target.new(self).tap do |target|
70
75
  target.precache_sources(sources)
@@ -74,7 +79,12 @@ module Librarian
74
79
  if block_given?
75
80
  receiver.run(&Proc.new)
76
81
  else
77
- receiver.run(specfile)
82
+ case specfile
83
+ when Specfile, String, Proc
84
+ receiver.run(specfile)
85
+ else
86
+ raise ArgumentError, "specfile must be a #{Specfile}, #{String}, or #{Proc} if no block is given (it was #{specfile.inspect})"
87
+ end
78
88
  end
79
89
 
80
90
  debug_named_source_cache("Post-Cached Sources", target)
@@ -33,6 +33,8 @@ module Librarian
33
33
  eval(specfile, instance_binding)
34
34
  when Proc
35
35
  instance_eval(&specfile)
36
+ else
37
+ raise ArgumentError, "specfile must be a #{Specfile}, #{String}, or #{Proc} if no block is given (it was #{specfile.inspect})"
36
38
  end
37
39
  end
38
40
  end
@@ -1,9 +1,13 @@
1
+ require 'librarian/helpers/debug'
2
+
1
3
  require 'librarian/spec'
2
4
 
3
5
  module Librarian
4
6
  class Dsl
5
7
  class Target
6
8
 
9
+ include Helpers::Debug
10
+
7
11
  class SourceShortcutDefinitionReceiver
8
12
  def initialize(target)
9
13
  singleton_class = class << self; self end
@@ -24,11 +28,15 @@ module Librarian
24
28
 
25
29
  SCOPABLES = [:sources]
26
30
 
31
+ attr_accessor :dsl
32
+ private :dsl=
33
+
27
34
  attr_reader :dependency_name, :dependency_type
28
35
  attr_reader :source_types, :source_types_map, :source_types_reverse_map, :source_type_names, :source_shortcuts
29
36
  attr_reader :dependencies, :source_cache, *SCOPABLES
30
37
 
31
38
  def initialize(dsl)
39
+ self.dsl = dsl
32
40
  @dependency_name = dsl.dependency_name
33
41
  @dependency_type = dsl.dependency_type
34
42
  @source_types = dsl.source_types
@@ -138,7 +146,7 @@ module Librarian
138
146
  def source_from_params(name, param, options)
139
147
  source_cache[[name, param, options]] ||= begin
140
148
  type = source_types_map[name]
141
- type.new(param, options)
149
+ type.new(environment, param, options)
142
150
  end
143
151
  end
144
152
 
@@ -159,6 +167,10 @@ module Librarian
159
167
  source_shortcuts[name] = source
160
168
  end
161
169
 
170
+ def environment
171
+ dsl.environment
172
+ end
173
+
162
174
  end
163
175
  end
164
176
  end
@@ -0,0 +1,94 @@
1
+ require "pathname"
2
+
3
+ require "librarian/helpers/debug"
4
+ require "librarian/support/abstract_method"
5
+
6
+ require "librarian/error"
7
+ require "librarian/lockfile"
8
+ require "librarian/specfile"
9
+ require "librarian/resolver"
10
+ require "librarian/dsl"
11
+
12
+ module Librarian
13
+ class Environment
14
+
15
+ include Support::AbstractMethod
16
+ include Helpers::Debug
17
+
18
+ attr_accessor :ui
19
+
20
+ abstract_method :specfile_name, :dsl_class, :install_path
21
+
22
+ def initialize(options = { })
23
+ @project_path = options[:project_path]
24
+ end
25
+
26
+ def project_path
27
+ @project_path ||= begin
28
+ root = Pathname.new(Dir.pwd)
29
+ root = root.dirname until root.join(specfile_name).exist? || root.dirname == root
30
+ path = root.join(specfile_name)
31
+ path.exist? ? root : nil
32
+ end
33
+ end
34
+
35
+ def specfile_path
36
+ project_path.join(specfile_name)
37
+ end
38
+
39
+ def specfile
40
+ Specfile.new(self, specfile_path)
41
+ end
42
+
43
+ def lockfile_name
44
+ "#{specfile_name}.lock"
45
+ end
46
+
47
+ def lockfile_path
48
+ project_path.join(lockfile_name)
49
+ end
50
+
51
+ def lockfile
52
+ Lockfile.new(self, lockfile_path)
53
+ end
54
+
55
+ def ephemeral_lockfile
56
+ Lockfile.new(self, nil)
57
+ end
58
+
59
+ def resolver
60
+ Resolver.new(self)
61
+ end
62
+
63
+ def cache_path
64
+ project_path.join("tmp/librarian/cache")
65
+ end
66
+
67
+ def project_relative_path_to(path)
68
+ Pathname.new(path).relative_path_from(project_path)
69
+ end
70
+
71
+ def spec
72
+ specfile.read
73
+ end
74
+
75
+ def lock
76
+ lockfile.read
77
+ end
78
+
79
+ def dsl(&block)
80
+ dsl_class.run(self, &block)
81
+ end
82
+
83
+ def dsl_class
84
+ self.class.name.split("::")[0 ... -1].inject(Object) { |constant, fragment| constant.const_get(fragment) }::Dsl
85
+ end
86
+
87
+ private
88
+
89
+ def environment
90
+ self
91
+ end
92
+
93
+ end
94
+ end