packs-specification 0.0.8 → 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.
- checksums.yaml +4 -4
- data/README.md +20 -19
- data/lib/packs/pack.rb +2 -2
- data/lib/packs/rspec/support.rb +12 -6
- data/lib/packs/{private → specification}/configuration.rb +1 -1
- data/lib/packs/specification.rb +73 -0
- data/lib/packs-specification.rb +7 -54
- metadata +4 -4
- data/lib/packs/private.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a95a4c598305baa6990d07093e98b49f55c3289c80d384e7beb558bcafde63ca
|
4
|
+
data.tar.gz: b6f2537d04165bee29925da1d29d9613da1b0219227ab397973efc65a1e64259
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4cc9f93bad4fd2fe25d1d5ac32c4895d6dfcdf64de56b0f6aec31b29129a9a9f902e62f8c5820972efee538e0ecf6f45efd976f2b2bf8dcff577f2369c62d68f
|
7
|
+
data.tar.gz: 0cb00ea631d12ee411150657650da2864303e24c92ce3747471e9328a4018478d490db599f94e3b69e9b9727259e6b4fe5e2ca51e80e881c8e8ec3384b328e00
|
data/README.md
CHANGED
@@ -1,25 +1,26 @@
|
|
1
1
|
# packs-specification
|
2
|
+
This is a low-dependency gem that allows your production environment to query simple information about [`packs`](https://github.com/rubyatscale/packs).
|
2
3
|
|
3
|
-
Welcome to `packs-specification`! `packs` are a simple ruby specification for an extensible packaging system to help modularize Ruby applications.
|
4
4
|
|
5
|
-
|
5
|
+
## Usage
|
6
|
+
```ruby
|
6
7
|
|
7
|
-
|
8
|
-
By default, this library will look for `packs` in the folder `packs/*/package.yml` (as well as nested packs at `packs/*/*/package.yml`). To change where `packs` are located, create a `packs.yml` file:
|
9
|
-
```
|
10
|
-
pack_paths:
|
11
|
-
- "{packs,utilities,deprecated}/*" # packs with multiple roots!
|
12
|
-
- "{packs,utilities,deprecated}/*/*" # nested packs!
|
13
|
-
- gems/* # gems can be packs too!
|
14
|
-
```
|
8
|
+
require 'packs-specification'
|
15
9
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- [`code_ownership`](https://github.com/rubyatscale/code_ownership) gives your application the capability to determine the owner of a pack
|
21
|
-
- [`use_packs`](https://github.com/rubyatscale/use_packs) gives a CLI, `bin/packs`, that makes it easy to create new packs, move files between packs, and more.
|
22
|
-
- [`pack_stats`](https://github.com/rubyatscale/pack_stats) makes it easy to send metrics about pack adoption and modularization to your favorite metrics provider, such as DataDog (which has built-in support).
|
10
|
+
# Getting all packs
|
11
|
+
# Example use: adding pack paths to a list of fixture paths
|
12
|
+
# Returns a T::Array[Packs::Pack]
|
13
|
+
Packs.all
|
23
14
|
|
24
|
-
#
|
25
|
-
|
15
|
+
# Getting the pack for a specific file
|
16
|
+
# Example use: Associating a file with an owner via a pack owner
|
17
|
+
# Returns a T.nilable(Packs::Pack)
|
18
|
+
Packs.for_file('/path/to/file.rb')
|
19
|
+
Packs.for_file(Pathname.new('/path/to/file.rb')) # also works
|
20
|
+
|
21
|
+
# Getting a pack with a specific name
|
22
|
+
# Example use: Special casing certain behavior for a specific pack
|
23
|
+
# Example use: Development tools that operate on user inputted pack names
|
24
|
+
# Returns a T.nilable(Packs::Pack)
|
25
|
+
Packs.find('packs/my_pack')
|
26
|
+
```
|
data/lib/packs/pack.rb
CHANGED
@@ -13,7 +13,7 @@ module Packs
|
|
13
13
|
def self.from(package_yml_absolute_path)
|
14
14
|
package_loaded_yml = YAML.load_file(package_yml_absolute_path)
|
15
15
|
path = package_yml_absolute_path.dirname
|
16
|
-
relative_path = path.relative_path_from(
|
16
|
+
relative_path = path.relative_path_from(Specification.root)
|
17
17
|
package_name = relative_path.cleanpath.to_s
|
18
18
|
|
19
19
|
Pack.new(
|
@@ -36,7 +36,7 @@ module Packs
|
|
36
36
|
end
|
37
37
|
|
38
38
|
sig { returns(T::Boolean) }
|
39
|
-
def is_gem?
|
39
|
+
def is_gem? # rubocop:disable Naming/PredicateName
|
40
40
|
@is_gem ||= T.let(relative_path.glob('*.gemspec').any?, T.nilable(T::Boolean))
|
41
41
|
end
|
42
42
|
|
data/lib/packs/rspec/support.rb
CHANGED
@@ -5,17 +5,23 @@ RSpec.configure do |config|
|
|
5
5
|
|
6
6
|
config.before do
|
7
7
|
# We bust_cache always because each test may write its own packs
|
8
|
-
Packs.bust_cache!
|
8
|
+
Packs::Specification.bust_cache!
|
9
9
|
end
|
10
10
|
|
11
11
|
# Eventually, we could make this opt-in via metadata so someone can use this support without affecting all their tests.
|
12
12
|
config.around do |example|
|
13
|
-
|
14
|
-
tmpdir = Dir.mktmpdir(prefix)
|
15
|
-
Dir.chdir(tmpdir) do
|
13
|
+
if example.metadata[:skip_chdir_to_tmpdir]
|
16
14
|
example.run
|
15
|
+
else
|
16
|
+
begin
|
17
|
+
prefix = [File.basename($0), Process.pid].join('-') # rubocop:disable Style/SpecialGlobalVars
|
18
|
+
tmpdir = Dir.mktmpdir(prefix)
|
19
|
+
Dir.chdir(tmpdir) do
|
20
|
+
example.run
|
21
|
+
end
|
22
|
+
ensure
|
23
|
+
FileUtils.rm_rf(tmpdir)
|
24
|
+
end
|
17
25
|
end
|
18
|
-
ensure
|
19
|
-
FileUtils.rm_rf(tmpdir)
|
20
26
|
end
|
21
27
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# typed: strict
|
2
|
+
|
3
|
+
require 'packs/specification/configuration'
|
4
|
+
|
5
|
+
module Packs
|
6
|
+
module Specification
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
class << self
|
10
|
+
extend T::Sig
|
11
|
+
|
12
|
+
sig { returns(Pathname) }
|
13
|
+
def root
|
14
|
+
Pathname.pwd
|
15
|
+
end
|
16
|
+
|
17
|
+
sig { returns(Configuration) }
|
18
|
+
def config
|
19
|
+
@config = T.let(@config, T.nilable(Configuration))
|
20
|
+
@config ||= Configuration.fetch
|
21
|
+
end
|
22
|
+
|
23
|
+
sig { void }
|
24
|
+
def bust_cache!
|
25
|
+
@packs_by_name = nil
|
26
|
+
@for_file = nil
|
27
|
+
@config = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
sig { returns(T::Array[Pack]) }
|
31
|
+
def all
|
32
|
+
packs_by_name.values
|
33
|
+
end
|
34
|
+
|
35
|
+
sig { params(name: String).returns(T.nilable(Pack)) }
|
36
|
+
def find(name)
|
37
|
+
packs_by_name[name]
|
38
|
+
end
|
39
|
+
|
40
|
+
sig { params(file_path: T.any(Pathname, String)).returns(T.nilable(Pack)) }
|
41
|
+
def for_file(file_path)
|
42
|
+
path_string = file_path.to_s
|
43
|
+
@for_file = T.let(@for_file, T.nilable(T::Hash[String, T.nilable(Pack)]))
|
44
|
+
@for_file ||= {}
|
45
|
+
@for_file[path_string] ||= all.find { |package| path_string.start_with?("#{package.name}/") || path_string == package.name }
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
sig { returns(T::Hash[String, Pack]) }
|
51
|
+
def packs_by_name
|
52
|
+
@packs_by_name = T.let(@packs_by_name, T.nilable(T::Hash[String, Pack]))
|
53
|
+
@packs_by_name ||= begin
|
54
|
+
all_packs = package_glob_patterns.map do |path|
|
55
|
+
Pack.from(path)
|
56
|
+
end
|
57
|
+
|
58
|
+
# We want to match more specific paths first so for_file works correctly.
|
59
|
+
sorted_packages = all_packs.sort_by { |package| -package.name.length }
|
60
|
+
sorted_packages.to_h { |p| [p.name, p] }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
sig { returns(T::Array[Pathname]) }
|
65
|
+
def package_glob_patterns
|
66
|
+
absolute_root = Specification.root
|
67
|
+
Specification.config.pack_paths.flat_map do |pack_path|
|
68
|
+
Pathname.glob(absolute_root.join(pack_path).join(PACKAGE_FILE))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/packs-specification.rb
CHANGED
@@ -4,8 +4,11 @@ require 'yaml'
|
|
4
4
|
require 'pathname'
|
5
5
|
require 'sorbet-runtime'
|
6
6
|
require 'packs/pack'
|
7
|
-
require 'packs/
|
7
|
+
require 'packs/specification'
|
8
8
|
|
9
|
+
# We let `packs-specification` define some API methods such as all, find, and for_file,
|
10
|
+
# because this allows a production environment to require `packs-specification` only and get some simple functionality, without
|
11
|
+
# needing to load all of `packs`.
|
9
12
|
module Packs
|
10
13
|
PACKAGE_FILE = T.let('package.yml'.freeze, String)
|
11
14
|
|
@@ -14,67 +17,17 @@ module Packs
|
|
14
17
|
|
15
18
|
sig { returns(T::Array[Pack]) }
|
16
19
|
def all
|
17
|
-
|
20
|
+
Specification.all
|
18
21
|
end
|
19
22
|
|
20
23
|
sig { params(name: String).returns(T.nilable(Pack)) }
|
21
24
|
def find(name)
|
22
|
-
|
25
|
+
Specification.find(name)
|
23
26
|
end
|
24
27
|
|
25
28
|
sig { params(file_path: T.any(Pathname, String)).returns(T.nilable(Pack)) }
|
26
29
|
def for_file(file_path)
|
27
|
-
|
28
|
-
@for_file = T.let(@for_file, T.nilable(T::Hash[String, T.nilable(Pack)]))
|
29
|
-
@for_file ||= {}
|
30
|
-
@for_file[path_string] ||= all.find { |package| path_string.start_with?("#{package.name}/") || path_string == package.name }
|
31
|
-
end
|
32
|
-
|
33
|
-
sig { void }
|
34
|
-
def bust_cache!
|
35
|
-
@packs_by_name = nil
|
36
|
-
@config = nil
|
37
|
-
@for_file = nil
|
38
|
-
end
|
39
|
-
|
40
|
-
sig { returns(Private::Configuration) }
|
41
|
-
def config
|
42
|
-
@config = T.let(@config, T.nilable(Private::Configuration))
|
43
|
-
@config ||= Private::Configuration.fetch
|
44
|
-
end
|
45
|
-
|
46
|
-
sig { params(blk: T.proc.params(arg0: Private::Configuration).void).void }
|
47
|
-
def configure(&blk)
|
48
|
-
# If packs.yml is being used, then ignore direct configuration.
|
49
|
-
# This is only a stop-gap to permit Stimpack users to more easily migrate
|
50
|
-
# to packs.yml
|
51
|
-
return if Private::Configuration::CONFIGURATION_PATHNAME.exist?
|
52
|
-
|
53
|
-
yield(config)
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
|
58
|
-
sig { returns(T::Hash[String, Pack]) }
|
59
|
-
def packs_by_name
|
60
|
-
@packs_by_name = T.let(@packs_by_name, T.nilable(T::Hash[String, Pack]))
|
61
|
-
@packs_by_name ||= begin
|
62
|
-
all_packs = package_glob_patterns.map do |path|
|
63
|
-
Pack.from(path)
|
64
|
-
end
|
65
|
-
|
66
|
-
# We want to match more specific paths first so for_file works correctly.
|
67
|
-
sorted_packages = all_packs.sort_by { |package| -package.name.length }
|
68
|
-
sorted_packages.to_h { |p| [p.name, p] }
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
sig { returns(T::Array[Pathname]) }
|
73
|
-
def package_glob_patterns
|
74
|
-
absolute_root = Private.root
|
75
|
-
config.pack_paths.flat_map do |pack_path|
|
76
|
-
Pathname.glob(absolute_root.join(pack_path).join(PACKAGE_FILE))
|
77
|
-
end
|
30
|
+
Specification.for_file(file_path)
|
78
31
|
end
|
79
32
|
end
|
80
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packs-specification
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gusto Engineers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sorbet-runtime
|
@@ -118,10 +118,10 @@ files:
|
|
118
118
|
- README.md
|
119
119
|
- lib/packs-specification.rb
|
120
120
|
- lib/packs/pack.rb
|
121
|
-
- lib/packs/private.rb
|
122
|
-
- lib/packs/private/configuration.rb
|
123
121
|
- lib/packs/rspec/fixture_helper.rb
|
124
122
|
- lib/packs/rspec/support.rb
|
123
|
+
- lib/packs/specification.rb
|
124
|
+
- lib/packs/specification/configuration.rb
|
125
125
|
homepage: https://github.com/rubyatscale/packs-specification
|
126
126
|
licenses:
|
127
127
|
- MIT
|
data/lib/packs/private.rb
DELETED