librarian 0.0.23 → 0.0.24
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 +17 -0
- data/Gemfile +2 -0
- data/README.md +97 -12
- data/features/chef/cli/init.feature +1 -0
- data/features/chef/cli/show.feature +12 -0
- data/lib/librarian/chef/cli.rb +20 -0
- data/lib/librarian/chef/environment.rb +9 -1
- data/lib/librarian/chef/source/git.rb +13 -0
- data/lib/librarian/chef/source/local.rb +6 -2
- data/lib/librarian/cli.rb +45 -20
- data/lib/librarian/config.rb +7 -0
- data/lib/librarian/config/database.rb +205 -0
- data/lib/librarian/config/file_source.rb +47 -0
- data/lib/librarian/config/hash_source.rb +33 -0
- data/lib/librarian/config/source.rb +149 -0
- data/lib/librarian/environment.rb +26 -24
- data/lib/librarian/source/git/repository.rb +2 -2
- data/lib/librarian/version.rb +1 -1
- data/librarian.gemspec +7 -4
- data/spec/functional/source/git/repository_spec.rb +149 -0
- data/spec/unit/config/database_spec.rb +319 -0
- metadata +92 -22
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.0.24
|
4
|
+
|
5
|
+
* \#15. A remembered configuration system.
|
6
|
+
|
7
|
+
* \#16. Configure, and remember configuration for, chef install paths.
|
8
|
+
|
9
|
+
* \#38. Configure, and remember configuration for, stripping out `.git`
|
10
|
+
directories from git-sources chef dependencies.
|
11
|
+
|
12
|
+
* \#76. Support git annotated tags.
|
13
|
+
|
14
|
+
* \#80. Ignore directories in the `PATH` named `git` when looking for the `git`
|
15
|
+
bin.
|
16
|
+
|
17
|
+
* \#85. Provide a helpful message when running the `show` command without a
|
18
|
+
lockfile present.
|
19
|
+
|
3
20
|
## 0.0.23
|
4
21
|
|
5
22
|
* \#41. Build gems with a built gemspec.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -12,33 +12,49 @@ A bundler written with Librarian will expect you to provide a specfile listing
|
|
12
12
|
your project's declared dependencies, including any version constraints and
|
13
13
|
including the upstream sources for finding them. Librarian can resolve the spec,
|
14
14
|
write a lockfile listing the full resolution, fetch the resolved dependencies,
|
15
|
-
install them, and isolate them in your project.
|
16
|
-
|
15
|
+
install them, and isolate them in your project.
|
16
|
+
|
17
|
+
A bundler written with Librarian will be similar in kind to [Bundler](http://gembundler.com),
|
18
|
+
the bundler for Ruby gems that many modern Rails applications use.
|
17
19
|
|
18
20
|
Librarian-Chef
|
19
21
|
---------------
|
20
22
|
|
23
|
+
Librarian-Chef is a tool that helps you manage the cookbooks that your chef-repo
|
24
|
+
depends on. Here are some more details.
|
25
|
+
|
21
26
|
Librarian-Chef is a bundler for infrastructure repositories using Chef. You can
|
22
|
-
use Librarian-Chef to resolve your infrastructure's cookbook dependencies,
|
23
|
-
|
27
|
+
use Librarian-Chef to resolve your infrastructure's cookbook dependencies, fetch
|
28
|
+
them, and install them into your infrastructure repository.
|
29
|
+
|
30
|
+
Librarian-Chef can resolve and fetch third-party, publicly-released cookbooks,
|
31
|
+
and install them into your infrastructure repository. It can also source
|
32
|
+
cookbooks directly from their own source control repositories.
|
33
|
+
|
34
|
+
Librarian-Chef can also deal with cookbooks you may actively be working on
|
35
|
+
outside your infrastructure repository. For example, it can deal with cookbooks
|
36
|
+
directly from their own private source control repositories, whether they are
|
37
|
+
remote or local to your machine, and it can deal with cookbooks released to and
|
38
|
+
hosted on a private cookbooks server.
|
24
39
|
|
25
|
-
Librarian-Chef is for
|
26
|
-
|
27
|
-
|
28
|
-
infrastructure repository.
|
40
|
+
Librarian-Chef is not primarily intended for dealing with the cookbooks you are
|
41
|
+
actively working on *within* your infrastructure repository. In such a case, you
|
42
|
+
can still use Librarian-Chef, but it is likely unnecessary.
|
29
43
|
|
30
44
|
Librarian-Chef *takes over* your `cookbooks/` directory and manages it for you
|
31
45
|
based on your `Cheffile`. Your `Cheffile` becomes the authoritative source for
|
32
46
|
the cookbooks your infrastructure repository depends on. You should not modify
|
33
47
|
the contents of your `cookbooks/` directory when using Librarian-Chef. If you
|
34
|
-
have
|
35
|
-
they should go in
|
48
|
+
have cookbooks which are, rather than being separate projects, inherently part
|
49
|
+
of your infrastructure repository, then they should go in a separate directory,
|
50
|
+
like your `site-cookbooks/` directory, and you do not need to use Librarian-Chef
|
51
|
+
to manage them.
|
36
52
|
|
37
53
|
### The Cheffile
|
38
54
|
|
39
55
|
Every infrastruture repository that uses Librarian-Chef will have a file named
|
40
56
|
`Cheffile` in the root directory of that repository. The full specification for
|
41
|
-
which third-party, publicly-
|
57
|
+
which third-party, publicly-released cookbooks your infrastructure repository
|
42
58
|
depends will go here.
|
43
59
|
|
44
60
|
Here's an example `Cheffile`:
|
@@ -103,7 +119,7 @@ most recent version of the cookbook from that same branch.
|
|
103
119
|
|
104
120
|
The Git source also supports a `:path =>` option. If we use the path option,
|
105
121
|
Librarian-Chef will navigate down into the Git repository and only use the
|
106
|
-
specified subdirectory. Many people have the
|
122
|
+
specified subdirectory. Many people have the habit of having a single repository
|
107
123
|
with many cookbooks in it. If we need a cookbook from such a repository, we can
|
108
124
|
use the `:path =>` option here to help Librarian-Chef drill down and find the
|
109
125
|
cookbook subdirectory.
|
@@ -240,6 +256,75 @@ Upload the cookbooks to your chef-server:
|
|
240
256
|
|
241
257
|
$ knife cookbook upload --all
|
242
258
|
|
259
|
+
### Configuration
|
260
|
+
|
261
|
+
Configuration comes from three sources with the following highest-to-lowest
|
262
|
+
precedence:
|
263
|
+
|
264
|
+
* The local config (`./.librarian/chef/config`)
|
265
|
+
* The environment
|
266
|
+
* The global config (`~/.librarian/chef/config`)
|
267
|
+
|
268
|
+
You can inspect the final configuration with:
|
269
|
+
|
270
|
+
$ librarian-chef config
|
271
|
+
|
272
|
+
You can find out where a particular key is set with:
|
273
|
+
|
274
|
+
$ librarian-chef config KEY
|
275
|
+
|
276
|
+
You can set a key at the global level with:
|
277
|
+
|
278
|
+
$ librarian-chef config KEY VALUE --global
|
279
|
+
|
280
|
+
And remove it with:
|
281
|
+
|
282
|
+
$ librarian-chef config KEY --global --delete
|
283
|
+
|
284
|
+
You can set a key at the local level with:
|
285
|
+
|
286
|
+
$ librarian-chef config KEY VALUE --local
|
287
|
+
|
288
|
+
And remove it with:
|
289
|
+
|
290
|
+
$ librarian-chef config KEY --local --delete
|
291
|
+
|
292
|
+
You cannot set or delete environment-level config keys with the CLI.
|
293
|
+
|
294
|
+
Configuration set at either the global or local level will affect subsequent
|
295
|
+
invocations of `librarian-chef`. Configurations set at the environment level are
|
296
|
+
not saved and will not affect subsequent invocations of `librarian-chef`.
|
297
|
+
|
298
|
+
You can pass a config at the environment level by taking the original config key
|
299
|
+
and transforming it: replace hyphens (`-`) with underscores (`_`) and periods
|
300
|
+
(`.`) with doubled underscores (`__`), uppercase, and finally prefix with
|
301
|
+
`LIBRARIAN_CHEF_`. For example, to pass a config in the environment for the key
|
302
|
+
`part-one.part-two`, set the environment variable
|
303
|
+
`LIBRARIAN_CHEF_PART_ONE__PART_TWO`.
|
304
|
+
|
305
|
+
Configuration affects how various commands operate.
|
306
|
+
|
307
|
+
* The `path` config sets the cookbooks directory to install to. If a relative
|
308
|
+
path, it is relative to the directory containing the `Cheffile`. The
|
309
|
+
equivalent environment variable is `LIBRARIAN_CHEF_PATH`.
|
310
|
+
|
311
|
+
* The `install.strip-dot-git` config causes the `.git/` directory to be stripped
|
312
|
+
out when installing cookbooks from a git source. This must be set to exactly
|
313
|
+
"1" to cause this behavior. The equivalent environment variable is
|
314
|
+
`LIBRARIAN_CHEF_INSTALL__STRIP_DOT_GIT`.
|
315
|
+
|
316
|
+
Configuration can be set by passing specific options to other commands.
|
317
|
+
|
318
|
+
* The `path` config can be set at the local level by passing the `--path` option
|
319
|
+
to the `install` command. It can be unset at the local level by passing the
|
320
|
+
`--no-path` option to the `install` command. Note that if this is set at the
|
321
|
+
environment or global level then, even if `--no-path` is given as an option,
|
322
|
+
the environment or global config will be used.
|
323
|
+
|
324
|
+
* The `install.strip-dot-git` config can be set at the local level by passing
|
325
|
+
the `--strip-dot-git` option to the `install` command. It can be unset at the
|
326
|
+
local level by passing the `--no-strip-dot-git` option.
|
327
|
+
|
243
328
|
### Knife Integration
|
244
329
|
|
245
330
|
You can integrate your `knife.rb` with Librarian-Chef.
|
@@ -25,6 +25,18 @@ Feature: cli/show
|
|
25
25
|
|
26
26
|
|
27
27
|
|
28
|
+
Scenario: Showing al without a lockfile
|
29
|
+
Given I remove the file "Cheffile.lock"
|
30
|
+
When I run `librarian-chef show`
|
31
|
+
Then the exit status should be 1
|
32
|
+
Then the output should contain exactly:
|
33
|
+
"""
|
34
|
+
Be sure to install first!
|
35
|
+
|
36
|
+
"""
|
37
|
+
|
38
|
+
|
39
|
+
|
28
40
|
Scenario: Showing all
|
29
41
|
When I run `librarian-chef show`
|
30
42
|
Then the exit status should be 0
|
data/lib/librarian/chef/cli.rb
CHANGED
@@ -22,6 +22,26 @@ 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 "verbose", :type => :boolean, :default => false
|
27
|
+
option "line-numbers", :type => :boolean, :default => false
|
28
|
+
option "clean", :type => :boolean, :default => false
|
29
|
+
option "strip-dot-git", :type => :boolean
|
30
|
+
option "path", :type => :string
|
31
|
+
def install
|
32
|
+
ensure!
|
33
|
+
clean! if options["clean"]
|
34
|
+
if options.include?("strip-dot-git")
|
35
|
+
strip_dot_git_val = options["strip-dot-git"] ? "1" : nil
|
36
|
+
environment.config_db.local["install.strip-dot-git"] = strip_dot_git_val
|
37
|
+
end
|
38
|
+
if options.include?("path")
|
39
|
+
environment.config_db.local["path"] = options["path"]
|
40
|
+
end
|
41
|
+
resolve!
|
42
|
+
install!
|
43
|
+
end
|
44
|
+
|
25
45
|
end
|
26
46
|
end
|
27
47
|
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
|
@@ -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
|
@@ -19,8 +19,7 @@ module Librarian
|
|
19
19
|
install_path.rmtree
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
FileUtils.cp_r(found_path, install_path)
|
22
|
+
install_perform_step_copy!(found_path, install_path)
|
24
23
|
end
|
25
24
|
|
26
25
|
def fetch_version(name, extra)
|
@@ -33,6 +32,11 @@ module Librarian
|
|
33
32
|
|
34
33
|
private
|
35
34
|
|
35
|
+
def install_perform_step_copy!(found_path, install_path)
|
36
|
+
debug { "Copying #{relative_path_to(found_path)} to #{relative_path_to(install_path)}" }
|
37
|
+
FileUtils.cp_r(found_path, install_path)
|
38
|
+
end
|
39
|
+
|
36
40
|
def manifest_data(name)
|
37
41
|
@manifest_data ||= { }
|
38
42
|
@manifest_data[name] ||= fetch_manifest_data(name)
|
data/lib/librarian/cli.rb
CHANGED
@@ -57,28 +57,49 @@ module Librarian
|
|
57
57
|
say "librarian-#{root_module.version}"
|
58
58
|
end
|
59
59
|
|
60
|
+
desc "config", "Show or edit the config."
|
61
|
+
option "verbose", :type => :boolean, :default => false
|
62
|
+
option "line-numbers", :type => :boolean, :default => false
|
63
|
+
option "global", :type => :boolean, :default => false
|
64
|
+
option "local", :type => :boolean, :default => false
|
65
|
+
option "delete", :type => :boolean, :default => false
|
66
|
+
def config(key = nil, value = nil)
|
67
|
+
if key
|
68
|
+
raise Error, "cannot set both value and delete" if value && options["delete"]
|
69
|
+
if options["delete"]
|
70
|
+
raise Error, "must set either global or local" unless options["global"] ^ options["local"]
|
71
|
+
scope = options["global"] ? :global : options["local"] ? :local : nil
|
72
|
+
environment.config_db[key, scope] = nil
|
73
|
+
elsif value
|
74
|
+
raise Error, "must set either global or local" unless options["global"] ^ options["local"]
|
75
|
+
scope = options["global"] ? :global : options["local"] ? :local : nil
|
76
|
+
environment.config_db[key, scope] = value
|
77
|
+
else
|
78
|
+
raise Error, "cannot set both global and local" if options["global"] && options["local"]
|
79
|
+
scope = options["global"] ? :global : options["local"] ? :local : nil
|
80
|
+
if value = environment.config_db[key, scope]
|
81
|
+
prefix = scope ? "#{key} (#{scope})" : key
|
82
|
+
say "#{prefix}: #{value}"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
else
|
86
|
+
environment.config_db.keys.each do |key|
|
87
|
+
say "#{key}: #{environment.config_db[key]}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
60
92
|
desc "clean", "Cleans out the cache and install paths."
|
61
|
-
option "verbose"
|
62
|
-
option "line-numbers"
|
93
|
+
option "verbose", :type => :boolean, :default => false
|
94
|
+
option "line-numbers", :type => :boolean, :default => false
|
63
95
|
def clean
|
64
96
|
ensure!
|
65
97
|
clean!
|
66
98
|
end
|
67
99
|
|
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
100
|
desc "update", "Updates and installs the dependencies you specify."
|
80
|
-
option "verbose"
|
81
|
-
option "line-numbers"
|
101
|
+
option "verbose", :type => :boolean, :default => false
|
102
|
+
option "line-numbers", :type => :boolean, :default => false
|
82
103
|
def update(*names)
|
83
104
|
ensure!
|
84
105
|
if names.empty?
|
@@ -90,8 +111,8 @@ module Librarian
|
|
90
111
|
end
|
91
112
|
|
92
113
|
desc "outdated", "Lists outdated dependencies."
|
93
|
-
option "verbose"
|
94
|
-
option "line-numbers"
|
114
|
+
option "verbose", :type => :boolean, :default => false
|
115
|
+
option "line-numbers", :type => :boolean, :default => false
|
95
116
|
def outdated
|
96
117
|
ensure!
|
97
118
|
resolution = environment.lock
|
@@ -104,12 +125,16 @@ module Librarian
|
|
104
125
|
end
|
105
126
|
|
106
127
|
desc "show", "Shows dependencies"
|
107
|
-
option "verbose"
|
108
|
-
option "line-numbers"
|
128
|
+
option "verbose", :type => :boolean, :default => false
|
129
|
+
option "line-numbers", :type => :boolean, :default => false
|
109
130
|
option "detailed", :type => :boolean
|
110
131
|
def show(*names)
|
111
132
|
ensure!
|
112
|
-
|
133
|
+
if environment.lockfile_path.file?
|
134
|
+
manifest_presenter.present(names, :detailed => options["detailed"])
|
135
|
+
else
|
136
|
+
raise Error, "Be sure to install first!"
|
137
|
+
end
|
113
138
|
end
|
114
139
|
|
115
140
|
desc "init", "Initializes the current directory."
|
@@ -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
|