Skip to content

Commit b870c88

Browse files
author
Alex Evanczuk
authored
Move API to Packs::Specification for more clarity on where the methods are defined (#19)
* move private * Move API under Specification submodule
1 parent 67d9b2a commit b870c88

10 files changed

Lines changed: 90 additions & 108 deletions

File tree

.rubocop.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,7 @@ Style/NumericPredicate:
116116

117117
Layout/BlockEndNewline:
118118
Enabled: false
119+
120+
Naming/FileName:
121+
Exclude:
122+
- lib/packs-specification.rb

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
packs-specification (0.0.8)
4+
packs-specification (0.0.9)
55
sorbet-runtime
66

77
GEM

lib/packs-specification.rb

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
require 'pathname'
55
require 'sorbet-runtime'
66
require 'packs/pack'
7-
require 'packs/private'
7+
require 'packs/specification'
88

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`.
912
module Packs
1013
PACKAGE_FILE = T.let('package.yml'.freeze, String)
1114

@@ -14,67 +17,17 @@ class << self
1417

1518
sig { returns(T::Array[Pack]) }
1619
def all
17-
packs_by_name.values
20+
Specification.all
1821
end
1922

2023
sig { params(name: String).returns(T.nilable(Pack)) }
2124
def find(name)
22-
packs_by_name[name]
25+
Specification.find(name)
2326
end
2427

2528
sig { params(file_path: T.any(Pathname, String)).returns(T.nilable(Pack)) }
2629
def for_file(file_path)
27-
path_string = file_path.to_s
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)
7831
end
7932
end
8033
end

lib/packs/pack.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Pack < T::Struct
1313
def self.from(package_yml_absolute_path)
1414
package_loaded_yml = YAML.load_file(package_yml_absolute_path)
1515
path = package_yml_absolute_path.dirname
16-
relative_path = path.relative_path_from(Private.root)
16+
relative_path = path.relative_path_from(Specification.root)
1717
package_name = relative_path.cleanpath.to_s
1818

1919
Pack.new(
@@ -36,7 +36,7 @@ def last_name
3636
end
3737

3838
sig { returns(T::Boolean) }
39-
def is_gem?
39+
def is_gem? # rubocop:disable Naming/PredicateName
4040
@is_gem ||= T.let(relative_path.glob('*.gemspec').any?, T.nilable(T::Boolean))
4141
end
4242

lib/packs/private.rb

Lines changed: 0 additions & 16 deletions
This file was deleted.

lib/packs/rspec/support.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
config.before do
77
# We bust_cache always because each test may write its own packs
8-
Packs.bust_cache!
8+
Packs::Specification.bust_cache!
99
end
1010

1111
# Eventually, we could make this opt-in via metadata so someone can use this support without affecting all their tests.

lib/packs/specification.rb

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# typed: strict
22

33
module Packs
4-
module Private
4+
module Specification
55
class Configuration < T::Struct
66
extend T::Sig
77
CONFIGURATION_PATHNAME = T.let(Pathname.new('packs.yml'), Pathname)

packs-specification.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Gem::Specification.new do |spec|
22
spec.name = 'packs-specification'
3-
spec.version = '0.0.8'
3+
spec.version = '0.0.9'
44
spec.authors = ['Gusto Engineers']
55
spec.email = ['dev@gusto.com']
66
spec.summary = 'The specification for packs in the `rubyatscale` ecosystem.'

spec/packs_spec.rb

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,38 +32,6 @@
3232

3333
it { expect(Packs.all.count).to eq 2 }
3434
end
35-
36-
context 'in an app with a differently configured root configured via ruby' do
37-
before do
38-
write_pack('packs/my_pack')
39-
write_pack('components/my_pack')
40-
Packs.configure do |config|
41-
config.pack_paths = ['packs/*', 'components/*']
42-
end
43-
end
44-
45-
it { expect(Packs.all.count).to eq 2 }
46-
end
47-
48-
context 'in an app with a differently configured root configured via ruby and YML' do
49-
before do
50-
write_pack('packs/my_pack')
51-
write_pack('components/my_pack')
52-
write_pack('packages/my_pack')
53-
write_file('packs.yml', <<~YML)
54-
pack_paths:
55-
- packs/*
56-
- components/*
57-
YML
58-
Packs.configure do |config|
59-
config.pack_paths = ['packs/*']
60-
end
61-
end
62-
63-
it 'prioritizes the YML configuration' do
64-
expect(Packs.all.count).to eq 2
65-
end
66-
end
6735
end
6836

6937
describe '.find' do

0 commit comments

Comments
 (0)