librarian-puppet 0.9.1 → 0.9.2.pre
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/lib/librarian/puppet.rb +6 -1
- data/lib/librarian/puppet/cli.rb +21 -0
- data/lib/librarian/puppet/environment.rb +1 -0
- data/lib/librarian/puppet/lockfile/parser.rb +53 -0
- data/lib/librarian/puppet/source/forge.rb +0 -8
- data/lib/librarian/puppet/source/git.rb +29 -0
- data/lib/librarian/puppet/source/local.rb +1 -0
- data/lib/librarian/puppet/version.rb +5 -0
- data/vendor/librarian/CHANGELOG.md +17 -0
- data/vendor/librarian/Gemfile +2 -0
- data/vendor/librarian/README.md +99 -14
- data/vendor/librarian/features/chef/cli/init.feature +1 -0
- data/vendor/librarian/features/chef/cli/show.feature +13 -1
- data/vendor/librarian/lib/librarian/action/base.rb +6 -4
- data/vendor/librarian/lib/librarian/chef/cli.rb +21 -0
- data/vendor/librarian/lib/librarian/chef/environment.rb +9 -1
- data/vendor/librarian/lib/librarian/chef/manifest_reader.rb +14 -2
- data/vendor/librarian/lib/librarian/chef/source/git.rb +13 -0
- data/vendor/librarian/lib/librarian/chef/source/local.rb +8 -2
- data/vendor/librarian/lib/librarian/chef/source/site.rb +18 -6
- data/vendor/librarian/lib/librarian/cli.rb +54 -24
- data/vendor/librarian/lib/librarian/config.rb +7 -0
- data/vendor/librarian/lib/librarian/config/database.rb +205 -0
- data/vendor/librarian/lib/librarian/config/file_source.rb +47 -0
- data/vendor/librarian/lib/librarian/config/hash_source.rb +33 -0
- data/vendor/librarian/lib/librarian/config/source.rb +149 -0
- data/vendor/librarian/lib/librarian/dependency.rb +1 -5
- data/vendor/librarian/lib/librarian/dsl.rb +6 -3
- data/vendor/librarian/lib/librarian/dsl/target.rb +0 -4
- data/vendor/librarian/lib/librarian/environment.rb +30 -25
- data/vendor/librarian/lib/librarian/lockfile.rb +0 -4
- data/vendor/librarian/lib/librarian/lockfile/compiler.rb +0 -4
- data/vendor/librarian/lib/librarian/lockfile/parser.rb +4 -8
- data/vendor/librarian/lib/librarian/logger.rb +46 -0
- data/vendor/librarian/lib/librarian/manifest.rb +1 -9
- data/vendor/librarian/lib/librarian/resolver.rb +6 -1
- data/vendor/librarian/lib/librarian/resolver/implementation.rb +1 -5
- data/vendor/librarian/lib/librarian/source/git/repository.rb +10 -6
- data/vendor/librarian/lib/librarian/source/local.rb +12 -2
- data/vendor/librarian/lib/librarian/spec_change_set.rb +6 -3
- data/vendor/librarian/lib/librarian/specfile.rb +0 -4
- data/vendor/librarian/lib/librarian/version.rb +1 -1
- data/vendor/librarian/librarian.gemspec +1 -0
- data/vendor/librarian/spec/functional/source/git/repository_spec.rb +149 -0
- data/vendor/librarian/spec/unit/config/database_spec.rb +319 -0
- data/vendor/librarian/spec/unit/dependency_spec.rb +6 -0
- data/vendor/librarian/spec/unit/manifest_spec.rb +6 -0
- metadata +107 -66
- data/librarian-puppet.gemspec +0 -130
- data/vendor/librarian/.rspec +0 -1
- data/vendor/librarian/.travis.yml +0 -6
- data/vendor/librarian/lib/librarian/helpers/debug.rb +0 -35
@@ -22,6 +22,27 @@ module Librarian
|
|
22
22
|
copy_file environment.specfile_name
|
23
23
|
end
|
24
24
|
|
25
|
+
desc "install", "Resolves and installs all of the dependencies you specify."
|
26
|
+
option "quiet", :type => :boolean, :default => false
|
27
|
+
option "verbose", :type => :boolean, :default => false
|
28
|
+
option "line-numbers", :type => :boolean, :default => false
|
29
|
+
option "clean", :type => :boolean, :default => false
|
30
|
+
option "strip-dot-git", :type => :boolean
|
31
|
+
option "path", :type => :string
|
32
|
+
def install
|
33
|
+
ensure!
|
34
|
+
clean! if options["clean"]
|
35
|
+
if options.include?("strip-dot-git")
|
36
|
+
strip_dot_git_val = options["strip-dot-git"] ? "1" : nil
|
37
|
+
environment.config_db.local["install.strip-dot-git"] = strip_dot_git_val
|
38
|
+
end
|
39
|
+
if options.include?("path")
|
40
|
+
environment.config_db.local["path"] = options["path"]
|
41
|
+
end
|
42
|
+
resolve!
|
43
|
+
install!
|
44
|
+
end
|
45
|
+
|
25
46
|
end
|
26
47
|
end
|
27
48
|
end
|
@@ -11,7 +11,15 @@ module Librarian
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def install_path
|
14
|
-
|
14
|
+
part = config_db["path"] || "cookbooks"
|
15
|
+
project_path.join(part)
|
16
|
+
end
|
17
|
+
|
18
|
+
def config_keys
|
19
|
+
super + %w[
|
20
|
+
install.strip-dot-git
|
21
|
+
path
|
22
|
+
]
|
15
23
|
end
|
16
24
|
|
17
25
|
end
|
@@ -16,8 +16,8 @@ module Librarian
|
|
16
16
|
|
17
17
|
def read_manifest(name, manifest_path)
|
18
18
|
case manifest_path.extname
|
19
|
-
when ".json" then JSON.parse(manifest_path
|
20
|
-
when ".yml", ".yaml" then YAML.load(manifest_path
|
19
|
+
when ".json" then JSON.parse(binread(manifest_path))
|
20
|
+
when ".yml", ".yaml" then YAML.load(binread(manifest_path))
|
21
21
|
when ".rb" then compile_manifest(name, manifest_path.dirname)
|
22
22
|
end
|
23
23
|
end
|
@@ -42,6 +42,18 @@ module Librarian
|
|
42
42
|
manifest["name"] == name
|
43
43
|
end
|
44
44
|
|
45
|
+
private
|
46
|
+
|
47
|
+
if IO.respond_to?(:binread)
|
48
|
+
def binread(path)
|
49
|
+
path.binread
|
50
|
+
end
|
51
|
+
else
|
52
|
+
def binread(path)
|
53
|
+
path.read
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
45
57
|
end
|
46
58
|
end
|
47
59
|
end
|
@@ -6,6 +6,19 @@ module Librarian
|
|
6
6
|
module Source
|
7
7
|
class Git < Librarian::Source::Git
|
8
8
|
include Local
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def install_perform_step_copy!(found_path, install_path)
|
13
|
+
debug { "Copying #{relative_path_to(found_path)} to #{relative_path_to(install_path)}" }
|
14
|
+
FileUtils.cp_r(found_path, install_path)
|
15
|
+
|
16
|
+
if environment.config_db["install.strip-dot-git"] == "1"
|
17
|
+
dot_git = install_path.join(".git")
|
18
|
+
dot_git.rmtree if dot_git.directory?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
9
22
|
end
|
10
23
|
end
|
11
24
|
end
|
@@ -8,6 +8,8 @@ module Librarian
|
|
8
8
|
def install!(manifest)
|
9
9
|
manifest.source == self or raise ArgumentError
|
10
10
|
|
11
|
+
info { "Installing #{manifest.name} (#{manifest.version})" }
|
12
|
+
|
11
13
|
debug { "Installing #{manifest}" }
|
12
14
|
|
13
15
|
name, version = manifest.name, manifest.version
|
@@ -19,8 +21,7 @@ module Librarian
|
|
19
21
|
install_path.rmtree
|
20
22
|
end
|
21
23
|
|
22
|
-
|
23
|
-
FileUtils.cp_r(found_path, install_path)
|
24
|
+
install_perform_step_copy!(found_path, install_path)
|
24
25
|
end
|
25
26
|
|
26
27
|
def fetch_version(name, extra)
|
@@ -33,6 +34,11 @@ module Librarian
|
|
33
34
|
|
34
35
|
private
|
35
36
|
|
37
|
+
def install_perform_step_copy!(found_path, install_path)
|
38
|
+
debug { "Copying #{relative_path_to(found_path)} to #{relative_path_to(install_path)}" }
|
39
|
+
FileUtils.cp_r(found_path, install_path)
|
40
|
+
end
|
41
|
+
|
36
42
|
def manifest_data(name)
|
37
43
|
@manifest_data ||= { }
|
38
44
|
@manifest_data[name] ||= fetch_manifest_data(name)
|
@@ -8,8 +8,6 @@ require 'zlib'
|
|
8
8
|
require 'securerandom'
|
9
9
|
require 'archive/tar/minitar'
|
10
10
|
|
11
|
-
require 'librarian/helpers/debug'
|
12
|
-
|
13
11
|
require 'librarian/chef/manifest_reader'
|
14
12
|
|
15
13
|
module Librarian
|
@@ -17,12 +15,8 @@ module Librarian
|
|
17
15
|
module Source
|
18
16
|
class Site
|
19
17
|
|
20
|
-
include Helpers::Debug
|
21
|
-
|
22
18
|
class Line
|
23
19
|
|
24
|
-
include Helpers::Debug
|
25
|
-
|
26
20
|
attr_accessor :source, :name
|
27
21
|
private :source=, :name=
|
28
22
|
|
@@ -313,6 +307,14 @@ module Librarian
|
|
313
307
|
uri
|
314
308
|
end
|
315
309
|
|
310
|
+
def debug(*args, &block)
|
311
|
+
environment.logger.debug(*args, &block)
|
312
|
+
end
|
313
|
+
|
314
|
+
def relative_path_to(path)
|
315
|
+
environment.logger.relative_path_to(path)
|
316
|
+
end
|
317
|
+
|
316
318
|
end
|
317
319
|
|
318
320
|
class << self
|
@@ -384,6 +386,8 @@ module Librarian
|
|
384
386
|
install_path = install_path(name)
|
385
387
|
line = line(name)
|
386
388
|
|
389
|
+
info { "Installing #{manifest.name} (#{manifest.version})" }
|
390
|
+
|
387
391
|
debug { "Installing #{manifest}" }
|
388
392
|
|
389
393
|
line.install_version! version, install_path
|
@@ -428,6 +432,14 @@ module Librarian
|
|
428
432
|
@line[name] ||= Line.new(self, name)
|
429
433
|
end
|
430
434
|
|
435
|
+
def info(*args, &block)
|
436
|
+
environment.logger.info(*args, &block)
|
437
|
+
end
|
438
|
+
|
439
|
+
def debug(*args, &block)
|
440
|
+
environment.logger.debug(*args, &block)
|
441
|
+
end
|
442
|
+
|
431
443
|
end
|
432
444
|
end
|
433
445
|
end
|
@@ -6,8 +6,6 @@ require 'librarian/error'
|
|
6
6
|
require 'librarian/action'
|
7
7
|
require "librarian/ui"
|
8
8
|
|
9
|
-
require "librarian/helpers/debug"
|
10
|
-
|
11
9
|
module Librarian
|
12
10
|
class Cli < Thor
|
13
11
|
|
@@ -24,8 +22,6 @@ module Librarian
|
|
24
22
|
include Particularity
|
25
23
|
extend Particularity
|
26
24
|
|
27
|
-
include Helpers::Debug
|
28
|
-
|
29
25
|
class << self
|
30
26
|
def bin!
|
31
27
|
begin
|
@@ -46,6 +42,7 @@ module Librarian
|
|
46
42
|
super
|
47
43
|
the_shell = (options["no-color"] ? Thor::Shell::Basic.new : shell)
|
48
44
|
environment.ui = UI::Shell.new(the_shell)
|
45
|
+
environment.ui.be_quiet! if options["quiet"]
|
49
46
|
environment.ui.debug! if options["verbose"]
|
50
47
|
environment.ui.debug_line_numbers! if options["verbose"] && options["line-numbers"]
|
51
48
|
|
@@ -57,28 +54,49 @@ module Librarian
|
|
57
54
|
say "librarian-#{root_module.version}"
|
58
55
|
end
|
59
56
|
|
57
|
+
desc "config", "Show or edit the config."
|
58
|
+
option "verbose", :type => :boolean, :default => false
|
59
|
+
option "line-numbers", :type => :boolean, :default => false
|
60
|
+
option "global", :type => :boolean, :default => false
|
61
|
+
option "local", :type => :boolean, :default => false
|
62
|
+
option "delete", :type => :boolean, :default => false
|
63
|
+
def config(key = nil, value = nil)
|
64
|
+
if key
|
65
|
+
raise Error, "cannot set both value and delete" if value && options["delete"]
|
66
|
+
if options["delete"]
|
67
|
+
raise Error, "must set either global or local" unless options["global"] ^ options["local"]
|
68
|
+
scope = options["global"] ? :global : options["local"] ? :local : nil
|
69
|
+
environment.config_db[key, scope] = nil
|
70
|
+
elsif value
|
71
|
+
raise Error, "must set either global or local" unless options["global"] ^ options["local"]
|
72
|
+
scope = options["global"] ? :global : options["local"] ? :local : nil
|
73
|
+
environment.config_db[key, scope] = value
|
74
|
+
else
|
75
|
+
raise Error, "cannot set both global and local" if options["global"] && options["local"]
|
76
|
+
scope = options["global"] ? :global : options["local"] ? :local : nil
|
77
|
+
if value = environment.config_db[key, scope]
|
78
|
+
prefix = scope ? "#{key} (#{scope})" : key
|
79
|
+
say "#{prefix}: #{value}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
else
|
83
|
+
environment.config_db.keys.each do |key|
|
84
|
+
say "#{key}: #{environment.config_db[key]}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
60
89
|
desc "clean", "Cleans out the cache and install paths."
|
61
|
-
option "verbose"
|
62
|
-
option "line-numbers"
|
90
|
+
option "verbose", :type => :boolean, :default => false
|
91
|
+
option "line-numbers", :type => :boolean, :default => false
|
63
92
|
def clean
|
64
93
|
ensure!
|
65
94
|
clean!
|
66
95
|
end
|
67
96
|
|
68
|
-
desc "install", "Resolves and installs all of the dependencies you specify."
|
69
|
-
option "verbose"
|
70
|
-
option "line-numbers"
|
71
|
-
option "clean"
|
72
|
-
def install
|
73
|
-
ensure!
|
74
|
-
clean! if options["clean"]
|
75
|
-
resolve!
|
76
|
-
install!
|
77
|
-
end
|
78
|
-
|
79
97
|
desc "update", "Updates and installs the dependencies you specify."
|
80
|
-
option "verbose"
|
81
|
-
option "line-numbers"
|
98
|
+
option "verbose", :type => :boolean, :default => false
|
99
|
+
option "line-numbers", :type => :boolean, :default => false
|
82
100
|
def update(*names)
|
83
101
|
ensure!
|
84
102
|
if names.empty?
|
@@ -90,8 +108,8 @@ module Librarian
|
|
90
108
|
end
|
91
109
|
|
92
110
|
desc "outdated", "Lists outdated dependencies."
|
93
|
-
option "verbose"
|
94
|
-
option "line-numbers"
|
111
|
+
option "verbose", :type => :boolean, :default => false
|
112
|
+
option "line-numbers", :type => :boolean, :default => false
|
95
113
|
def outdated
|
96
114
|
ensure!
|
97
115
|
resolution = environment.lock
|
@@ -104,12 +122,16 @@ module Librarian
|
|
104
122
|
end
|
105
123
|
|
106
124
|
desc "show", "Shows dependencies"
|
107
|
-
option "verbose"
|
108
|
-
option "line-numbers"
|
125
|
+
option "verbose", :type => :boolean, :default => false
|
126
|
+
option "line-numbers", :type => :boolean, :default => false
|
109
127
|
option "detailed", :type => :boolean
|
110
128
|
def show(*names)
|
111
129
|
ensure!
|
112
|
-
|
130
|
+
if environment.lockfile_path.file?
|
131
|
+
manifest_presenter.present(names, :detailed => options["detailed"])
|
132
|
+
else
|
133
|
+
raise Error, "Be sure to install first!"
|
134
|
+
end
|
113
135
|
end
|
114
136
|
|
115
137
|
desc "init", "Initializes the current directory."
|
@@ -171,5 +193,13 @@ module Librarian
|
|
171
193
|
end
|
172
194
|
end
|
173
195
|
|
196
|
+
def debug(*args, &block)
|
197
|
+
environment.logger.debug(*args, &block)
|
198
|
+
end
|
199
|
+
|
200
|
+
def relative_path_to(path)
|
201
|
+
environment.logger.relative_path_to(path)
|
202
|
+
end
|
203
|
+
|
174
204
|
end
|
175
205
|
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
require "librarian/config/file_source"
|
4
|
+
require "librarian/config/hash_source"
|
5
|
+
|
6
|
+
module Librarian
|
7
|
+
module Config
|
8
|
+
class Database
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def library
|
12
|
+
name.split("::").first.downcase
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :adapter_name
|
17
|
+
private :adapter_name=
|
18
|
+
|
19
|
+
attr_accessor :root, :assigned_specfile_name
|
20
|
+
private :root=, :assigned_specfile_name=
|
21
|
+
|
22
|
+
attr_accessor :underlying_env, :underlying_pwd, :underlying_home
|
23
|
+
private :underlying_env=, :underlying_pwd=, :underlying_home=
|
24
|
+
|
25
|
+
def initialize(adapter_name, options = { })
|
26
|
+
self.adapter_name = adapter_name or raise ArgumentError, "must provide adapter_name"
|
27
|
+
|
28
|
+
options[:project_path] || options[:pwd] or raise ArgumentError, "must provide project_path or pwd"
|
29
|
+
|
30
|
+
self.root = options[:project_path] && Pathname(options[:project_path])
|
31
|
+
self.assigned_specfile_name = options[:specfile_name]
|
32
|
+
self.underlying_env = options[:env] or raise ArgumentError, "must provide env"
|
33
|
+
self.underlying_pwd = options[:pwd] && Pathname(options[:pwd])
|
34
|
+
self.underlying_home = options[:home] && Pathname(options[:home])
|
35
|
+
end
|
36
|
+
|
37
|
+
def global
|
38
|
+
memo(__method__) { new_file_source(global_config_path) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def env
|
42
|
+
memo(__method__) { HashSource.new(adapter_name, :name => "environment", :raw => env_source_data) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def local
|
46
|
+
memo(__method__) { new_file_source(local_config_path) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def [](key, scope = nil)
|
50
|
+
case scope
|
51
|
+
when "local", :local then local[key]
|
52
|
+
when "env", :env then env[key]
|
53
|
+
when "global", :global then global[key]
|
54
|
+
when nil then local[key] || env[key] || global[key]
|
55
|
+
else raise Error, "bad scope"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def []=(key, scope, value)
|
60
|
+
case scope
|
61
|
+
when "local", :local then local[key] = value
|
62
|
+
when "global", :global then global[key] = value
|
63
|
+
else raise Error, "bad scope"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def keys
|
68
|
+
[local, env, global].inject([]){|a, e| a.concat(e.keys) ; a}.sort.uniq
|
69
|
+
end
|
70
|
+
|
71
|
+
def project_path
|
72
|
+
root || specfile_path.dirname
|
73
|
+
end
|
74
|
+
|
75
|
+
def specfile_path
|
76
|
+
if root
|
77
|
+
root + (assigned_specfile_name || default_specfile_name)
|
78
|
+
else
|
79
|
+
env_specfile_path || default_specfile_path
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def specfile_name
|
84
|
+
specfile_path.basename.to_s
|
85
|
+
end
|
86
|
+
|
87
|
+
def lockfile_path
|
88
|
+
project_path + lockfile_name
|
89
|
+
end
|
90
|
+
|
91
|
+
def lockfile_name
|
92
|
+
"#{specfile_name}.lock"
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def new_file_source(config_path)
|
98
|
+
return unless config_path
|
99
|
+
|
100
|
+
FileSource.new(adapter_name,
|
101
|
+
:config_path => config_path,
|
102
|
+
:forbidden_keys => [config_key, specfile_key]
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def global_config_path
|
107
|
+
env_global_config_path || default_global_config_path
|
108
|
+
end
|
109
|
+
|
110
|
+
def env_global_config_path
|
111
|
+
memo(__method__) { env[config_key] }
|
112
|
+
end
|
113
|
+
|
114
|
+
def default_global_config_path
|
115
|
+
underlying_home && underlying_home + config_name
|
116
|
+
end
|
117
|
+
|
118
|
+
def local_config_path
|
119
|
+
root_local_config_path || env_local_config_path || default_local_config_path
|
120
|
+
end
|
121
|
+
|
122
|
+
def root_local_config_path
|
123
|
+
root && root + config_name
|
124
|
+
end
|
125
|
+
|
126
|
+
def env_specfile_path
|
127
|
+
memo(__method__) do
|
128
|
+
path = env[specfile_key]
|
129
|
+
path && Pathname(path)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def default_specfile_path
|
134
|
+
default_project_root_path + (assigned_specfile_name || default_specfile_name)
|
135
|
+
end
|
136
|
+
|
137
|
+
def env_local_config_path
|
138
|
+
return unless env_specfile_path
|
139
|
+
|
140
|
+
env_specfile_path.dirname + config_name
|
141
|
+
end
|
142
|
+
|
143
|
+
def default_local_config_path
|
144
|
+
default_project_root_path + config_name
|
145
|
+
end
|
146
|
+
|
147
|
+
def default_project_root_path
|
148
|
+
if root
|
149
|
+
root
|
150
|
+
else
|
151
|
+
path = underlying_pwd
|
152
|
+
path = path.dirname until project_root_path?(path) || path.dirname == path
|
153
|
+
project_root_path?(path) ? path : underlying_pwd
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def project_root_path?(path)
|
158
|
+
File.file?(path + default_specfile_name)
|
159
|
+
end
|
160
|
+
|
161
|
+
def config_key
|
162
|
+
"config"
|
163
|
+
end
|
164
|
+
|
165
|
+
def specfile_key
|
166
|
+
"#{adapter_name}file"
|
167
|
+
end
|
168
|
+
|
169
|
+
def default_specfile_name
|
170
|
+
"#{adapter_name.capitalize}file"
|
171
|
+
end
|
172
|
+
|
173
|
+
def library
|
174
|
+
self.class.library
|
175
|
+
end
|
176
|
+
|
177
|
+
def config_name_prefix
|
178
|
+
".#{library}"
|
179
|
+
end
|
180
|
+
|
181
|
+
def config_name
|
182
|
+
File.join(*[config_name_prefix, adapter_name, "config"])
|
183
|
+
end
|
184
|
+
|
185
|
+
def raw_key_prefix
|
186
|
+
"#{library.upcase}_#{adapter_name.upcase}_"
|
187
|
+
end
|
188
|
+
|
189
|
+
def env_source_data
|
190
|
+
prefix = raw_key_prefix
|
191
|
+
|
192
|
+
data = underlying_env.dup
|
193
|
+
data.reject!{|k, _| !k.start_with?(prefix) || k.size <= prefix.size}
|
194
|
+
data
|
195
|
+
end
|
196
|
+
|
197
|
+
def memo(key)
|
198
|
+
key = "@#{key}"
|
199
|
+
instance_variable_set(key, yield) unless instance_variable_defined?(key)
|
200
|
+
instance_variable_get(key)
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|