librarian 0.0.9 → 0.0.10

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