code_ownership 1.29.1 → 1.29.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd3be735f88cd50d9ba9d9e3d73d6adbf58ebcb20aaa4bceaf3955deedaa497c
4
- data.tar.gz: 6a9ca2b07221580d8926218ab912ff418d7c24631a13b04767108e715f19ce57
3
+ metadata.gz: 0ea243e473ae151a2775f8e1e47d0eb9dacb27f3d2d594db63d3004f5c611109
4
+ data.tar.gz: eb77703d34e6c40ee734d3e487fd58ba0f124555a681ff267326a4a3f4aeb03e
5
5
  SHA512:
6
- metadata.gz: 4931c183eb23c08d0ca13bd1d6455c09aa69c9a5fce4f6b7387a3d4da4034c817c341bd74e38efe5bb958ec191f021d749fbb939bc03d9b956836d52e400b312
7
- data.tar.gz: a102028da11aefab9899f6eb194b4078846747f6afd2fea76d4e9aa78c66dfecb7c18f8f7482a02a5d43b8d8c4452b7d4492b2704aa3d07ebcdc238a89f363eb
6
+ metadata.gz: 8464d15022cc9a5f9e6019c0633b8941a3a5f1984f5d55f676c6377b94c335efb0b5722c4289f40b32da5f01453e806911c829c7fa0f11643f2d90c3327db3f3
7
+ data.tar.gz: 84c95502b0457b848d705b71b675c0d9b8654ed940cd3ba37bc1503c0d8c3cfe7b53dfa28340610ccfde17527e69facc14e7abb106843b21456b3fb17b3bc41d
data/README.md CHANGED
@@ -36,7 +36,7 @@ File annotations are a last resort if there is no clear home for your code. File
36
36
  ```
37
37
 
38
38
  ### Javascript Package Ownership
39
- Javascript package based ownership allows you to specify an owenrship key in a `package.json`. To use this, configure your `package.json` like this:
39
+ Javascript package based ownership allows you to specify an ownership key in a `package.json`. To use this, configure your `package.json` like this:
40
40
 
41
41
  ```json
42
42
  {
@@ -9,14 +9,14 @@ module CodeOwnership
9
9
  extend T::Sig
10
10
  include Interface
11
11
 
12
- @@package_yml_cache = T.let({}, T::Hash[String, T.nilable(ParsePackwerk::Package)]) # rubocop:disable Style/ClassVars
12
+ @@package_yml_cache = T.let({}, T::Hash[String, T.nilable(Packs::Pack)]) # rubocop:disable Style/ClassVars
13
13
 
14
14
  sig do
15
15
  override.params(file: String).
16
16
  returns(T.nilable(::CodeTeams::Team))
17
17
  end
18
18
  def map_file_to_owner(file)
19
- package = ParsePackwerk.package_from_path(file)
19
+ package = Packs.for_file(file)
20
20
 
21
21
  return nil if package.nil?
22
22
 
@@ -29,11 +29,11 @@ module CodeOwnership
29
29
  returns(T::Hash[String, T.nilable(::CodeTeams::Team)])
30
30
  end
31
31
  def map_files_to_owners(files) # rubocop:disable Lint/UnusedMethodArgument
32
- ParsePackwerk.all.each_with_object({}) do |package, res|
32
+ Packs.all.each_with_object({}) do |package, res|
33
33
  owner = owner_for_package(package)
34
34
  next if owner.nil?
35
35
 
36
- glob = package.directory.join('**/**').to_s
36
+ glob = package.relative_path.join('**/**').to_s
37
37
  Dir.glob(glob).each do |path|
38
38
  res[path] = owner
39
39
  end
@@ -52,11 +52,11 @@ module CodeOwnership
52
52
  override.returns(T::Hash[String, T.nilable(::CodeTeams::Team)])
53
53
  end
54
54
  def codeowners_lines_to_owners
55
- ParsePackwerk.all.each_with_object({}) do |package, res|
55
+ Packs.all.each_with_object({}) do |package, res|
56
56
  owner = owner_for_package(package)
57
57
  next if owner.nil?
58
58
 
59
- res[package.directory.join('**/**').to_s] = owner
59
+ res[package.relative_path.join('**/**').to_s] = owner
60
60
  end
61
61
  end
62
62
 
@@ -65,7 +65,7 @@ module CodeOwnership
65
65
  'Owner metadata key in package.yml'
66
66
  end
67
67
 
68
- sig { params(package: ParsePackwerk::Package).returns(T.nilable(CodeTeams::Team)) }
68
+ sig { params(package: Packs::Pack).returns(T.nilable(CodeTeams::Team)) }
69
69
  def owner_for_package(package)
70
70
  raw_owner_value = package.metadata['owner']
71
71
  return nil if !raw_owner_value
@@ -6,7 +6,7 @@ require 'set'
6
6
  require 'code_teams'
7
7
  require 'sorbet-runtime'
8
8
  require 'json'
9
- require 'parse_packwerk'
9
+ require 'packs'
10
10
  require 'code_ownership/cli'
11
11
  require 'code_ownership/private'
12
12
 
@@ -58,7 +58,6 @@ module CodeOwnership
58
58
  ownership_information += ownership_for_mapper
59
59
  end
60
60
 
61
-
62
61
  ownership_information << ""
63
62
  end
64
63
 
@@ -93,7 +92,25 @@ module CodeOwnership
93
92
  # first line that corresponds to a file with assigned ownership
94
93
  sig { params(backtrace: T.nilable(T::Array[String]), excluded_teams: T::Array[::CodeTeams::Team]).returns(T.nilable(::CodeTeams::Team)) }
95
94
  def for_backtrace(backtrace, excluded_teams: [])
96
- return unless backtrace
95
+ first_owned_file_for_backtrace(backtrace, excluded_teams: excluded_teams)&.first
96
+ end
97
+
98
+ # Given a backtrace from either `Exception#backtrace` or `caller`, find the
99
+ # first owned file in it, useful for figuring out which file is being blamed.
100
+ sig { params(backtrace: T.nilable(T::Array[String]), excluded_teams: T::Array[::CodeTeams::Team]).returns(T.nilable([::CodeTeams::Team, String])) }
101
+ def first_owned_file_for_backtrace(backtrace, excluded_teams: [])
102
+ backtrace_with_ownership(backtrace).each do |(team, file)|
103
+ if team && !excluded_teams.include?(team)
104
+ return [team, file]
105
+ end
106
+ end
107
+
108
+ nil
109
+ end
110
+
111
+ sig { params(backtrace: T.nilable(T::Array[String])).returns(T::Enumerable[[T.nilable(::CodeTeams::Team), String]]) }
112
+ def backtrace_with_ownership(backtrace)
113
+ return [] unless backtrace
97
114
 
98
115
  # The pattern for a backtrace hasn't changed in forever and is considered
99
116
  # stable: https://github.com/ruby/ruby/blob/trunk/vm_backtrace.c#L303-L317
@@ -110,18 +127,19 @@ module CodeOwnership
110
127
  `(?<function>.*)' # Matches "`block (3 levels) in create'"
111
128
  \z}x
112
129
 
113
- backtrace.each do |line|
130
+ backtrace.lazy.filter_map do |line|
114
131
  match = line.match(backtrace_line)
132
+ next unless match
115
133
 
116
- if match
117
- team = CodeOwnership.for_file(T.must(match[:file]))
118
- if team && !excluded_teams.include?(team)
119
- return team
120
- end
121
- end
134
+ file = T.must(match[:file])
135
+
136
+ [
137
+ CodeOwnership.for_file(file),
138
+ file,
139
+ ]
122
140
  end
123
- nil
124
141
  end
142
+ private_class_method(:backtrace_with_ownership)
125
143
 
126
144
  sig { params(klass: T.nilable(T.any(Class, Module))).returns(T.nilable(::CodeTeams::Team)) }
127
145
  def for_class(klass)
@@ -140,7 +158,7 @@ module CodeOwnership
140
158
  end
141
159
  end
142
160
 
143
- sig { params(package: ParsePackwerk::Package).returns(T.nilable(::CodeTeams::Team)) }
161
+ sig { params(package: Packs::Pack).returns(T.nilable(::CodeTeams::Team)) }
144
162
  def for_package(package)
145
163
  Private::OwnershipMappers::PackageOwnership.new.owner_for_package(package)
146
164
  end
@@ -0,0 +1,80 @@
1
+ # typed: true
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This is an autogenerated file for types exported from the `packs` gem.
5
+ # Please instead update this file by running `bin/tapioca gem packs`.
6
+
7
+ module Packs
8
+ class << self
9
+ sig { returns(T::Array[::Packs::Pack]) }
10
+ def all; end
11
+
12
+ sig { void }
13
+ def bust_cache!; end
14
+
15
+ sig { returns(::Packs::Configuration) }
16
+ def config; end
17
+
18
+ sig { params(blk: T.proc.params(arg0: ::Packs::Configuration).void).void }
19
+ def configure(&blk); end
20
+
21
+ sig { params(name: ::String).returns(T.nilable(::Packs::Pack)) }
22
+ def find(name); end
23
+
24
+ sig { params(file_path: T.any(::Pathname, ::String)).returns(T.nilable(::Packs::Pack)) }
25
+ def for_file(file_path); end
26
+
27
+ private
28
+
29
+ sig { returns(T::Array[::Pathname]) }
30
+ def package_glob_patterns; end
31
+
32
+ sig { returns(T::Hash[::String, ::Packs::Pack]) }
33
+ def packs_by_name; end
34
+ end
35
+ end
36
+
37
+ class Packs::Configuration
38
+ sig { void }
39
+ def initialize; end
40
+
41
+ sig { returns(T::Array[::Pathname]) }
42
+ def roots; end
43
+
44
+ sig { params(roots: T::Array[::String]).void }
45
+ def roots=(roots); end
46
+ end
47
+
48
+ Packs::PACKAGE_FILE = T.let(T.unsafe(nil), String)
49
+
50
+ class Packs::Pack < ::T::Struct
51
+ const :name, ::String
52
+ const :path, ::Pathname
53
+ const :raw_hash, T::Hash[T.untyped, T.untyped]
54
+ const :relative_path, ::Pathname
55
+
56
+ sig { returns(::String) }
57
+ def last_name; end
58
+
59
+ sig { returns(T::Hash[T.untyped, T.untyped]) }
60
+ def metadata; end
61
+
62
+ sig { returns(::Pathname) }
63
+ def yml; end
64
+
65
+ class << self
66
+ sig { params(package_yml_absolute_path: ::Pathname).returns(::Packs::Pack) }
67
+ def from(package_yml_absolute_path); end
68
+
69
+ def inherited(s); end
70
+ end
71
+ end
72
+
73
+ module Packs::Private
74
+ class << self
75
+ sig { returns(::Pathname) }
76
+ def root; end
77
+ end
78
+ end
79
+
80
+ Packs::ROOTS = T.let(T.unsafe(nil), Array)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_ownership
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.29.1
4
+ version: 1.29.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-30 00:00:00.000000000 Z
11
+ date: 2023-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: code_teams
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: parse_packwerk
28
+ name: packs
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -150,7 +150,7 @@ files:
150
150
  - lib/code_ownership/private/validations/interface.rb
151
151
  - sorbet/config
152
152
  - sorbet/rbi/gems/code_teams@1.0.0.rbi
153
- - sorbet/rbi/gems/parse_packwerk@0.12.0.rbi
153
+ - sorbet/rbi/gems/packs@0.0.2.rbi
154
154
  - sorbet/rbi/manual.rbi
155
155
  - sorbet/rbi/todo.rbi
156
156
  homepage: https://github.com/rubyatscale/code_ownership
@@ -1,146 +0,0 @@
1
- # typed: true
2
-
3
- # DO NOT EDIT MANUALLY
4
- # This is an autogenerated file for types exported from the `parse_packwerk` gem.
5
- # Please instead update this file by running `bin/tapioca gem parse_packwerk`.
6
-
7
- module ParsePackwerk
8
- class << self
9
- sig { returns(T::Array[::ParsePackwerk::Package]) }
10
- def all; end
11
-
12
- sig { void }
13
- def bust_cache!; end
14
-
15
- sig { params(name: ::String).returns(T.nilable(::ParsePackwerk::Package)) }
16
- def find(name); end
17
-
18
- sig { params(file_path: T.any(::Pathname, ::String)).returns(T.nilable(::ParsePackwerk::Package)) }
19
- def package_from_path(file_path); end
20
-
21
- sig { params(package: ::ParsePackwerk::Package).void }
22
- def write_package_yml!(package); end
23
-
24
- sig { returns(::ParsePackwerk::Configuration) }
25
- def yml; end
26
-
27
- private
28
-
29
- sig { returns(T::Hash[::String, ::ParsePackwerk::Package]) }
30
- def packages_by_name; end
31
- end
32
- end
33
-
34
- class ParsePackwerk::Configuration < ::T::Struct
35
- const :exclude, T::Array[::String]
36
- const :package_paths, T::Array[::String]
37
-
38
- class << self
39
- sig { params(config_hash: T::Hash[T.untyped, T.untyped]).returns(T::Array[::String]) }
40
- def excludes(config_hash); end
41
-
42
- sig { returns(::ParsePackwerk::Configuration) }
43
- def fetch; end
44
-
45
- def inherited(s); end
46
-
47
- sig { params(config_hash: T::Hash[T.untyped, T.untyped]).returns(T::Array[::String]) }
48
- def package_paths(config_hash); end
49
- end
50
- end
51
-
52
- ParsePackwerk::DEFAULT_EXCLUDE_GLOBS = T.let(T.unsafe(nil), Array)
53
- ParsePackwerk::DEFAULT_PACKAGE_PATHS = T.let(T.unsafe(nil), Array)
54
- ParsePackwerk::DEPENDENCIES = T.let(T.unsafe(nil), String)
55
- ParsePackwerk::DEPRECATED_REFERENCES_YML_NAME = T.let(T.unsafe(nil), String)
56
-
57
- class ParsePackwerk::DeprecatedReferences < ::T::Struct
58
- const :pathname, ::Pathname
59
- const :violations, T::Array[::ParsePackwerk::Violation]
60
-
61
- class << self
62
- sig { params(package: ::ParsePackwerk::Package).returns(::ParsePackwerk::DeprecatedReferences) }
63
- def for(package); end
64
-
65
- sig { params(pathname: ::Pathname).returns(::ParsePackwerk::DeprecatedReferences) }
66
- def from(pathname); end
67
-
68
- def inherited(s); end
69
- end
70
- end
71
-
72
- ParsePackwerk::ENFORCE_DEPENDENCIES = T.let(T.unsafe(nil), String)
73
- ParsePackwerk::ENFORCE_PRIVACY = T.let(T.unsafe(nil), String)
74
- ParsePackwerk::METADATA = T.let(T.unsafe(nil), String)
75
- ParsePackwerk::MetadataYmlType = T.type_alias { T::Hash[T.untyped, T.untyped] }
76
-
77
- class ParsePackwerk::MissingConfiguration < ::StandardError
78
- sig { params(packwerk_file_name: ::Pathname).void }
79
- def initialize(packwerk_file_name); end
80
- end
81
-
82
- ParsePackwerk::PACKAGE_YML_NAME = T.let(T.unsafe(nil), String)
83
- ParsePackwerk::PACKWERK_YML_NAME = T.let(T.unsafe(nil), String)
84
-
85
- class ParsePackwerk::Package < ::T::Struct
86
- const :dependencies, T::Array[::String]
87
- const :enforce_dependencies, T::Boolean
88
- const :enforce_privacy, T::Boolean
89
- const :metadata, T::Hash[T.untyped, T.untyped]
90
- const :name, ::String
91
-
92
- sig { returns(::Pathname) }
93
- def directory; end
94
-
95
- sig { returns(T::Boolean) }
96
- def enforces_dependencies?; end
97
-
98
- sig { returns(T::Boolean) }
99
- def enforces_privacy?; end
100
-
101
- sig { returns(::Pathname) }
102
- def yml; end
103
-
104
- class << self
105
- sig { params(pathname: ::Pathname).returns(::ParsePackwerk::Package) }
106
- def from(pathname); end
107
-
108
- def inherited(s); end
109
- end
110
- end
111
-
112
- class ParsePackwerk::PackageSet
113
- class << self
114
- sig do
115
- params(
116
- package_pathspec: T::Array[::String],
117
- exclude_pathspec: T::Array[::String]
118
- ).returns(T::Array[::ParsePackwerk::Package])
119
- end
120
- def from(package_pathspec:, exclude_pathspec:); end
121
-
122
- private
123
-
124
- sig { params(globs: T::Array[::String], path: ::Pathname).returns(T::Boolean) }
125
- def exclude_path?(globs, path); end
126
- end
127
- end
128
-
129
- ParsePackwerk::ROOT_PACKAGE_NAME = T.let(T.unsafe(nil), String)
130
-
131
- class ParsePackwerk::Violation < ::T::Struct
132
- const :class_name, ::String
133
- const :files, T::Array[::String]
134
- const :to_package_name, ::String
135
- const :type, ::String
136
-
137
- sig { returns(T::Boolean) }
138
- def dependency?; end
139
-
140
- sig { returns(T::Boolean) }
141
- def privacy?; end
142
-
143
- class << self
144
- def inherited(s); end
145
- end
146
- end