owners 0.0.9 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 20bc5ff50e8b6c0614a56bf72251c9dc8a1d059c
4
- data.tar.gz: a765f585fde8b708ee5ff77c3214af251eff0407
3
+ metadata.gz: 3ee93e4fe5cb329bf5df70608c572efa974963c4
4
+ data.tar.gz: 578b7e1c7ece642fa707b8499756c1424e2e77b0
5
5
  SHA512:
6
- metadata.gz: 6ccafca0dd0655c27e80103e06f7cc61dce514bb1f8c556b048851de1eddb43752db874eb331c85ec64d499fb620368b2d503376040d5eb1375bc80b24013e5e
7
- data.tar.gz: bfbd3c7370a857c1c090b2332e42ae1ff7007c7c4322ba992c168afb34fa6e2bd43ca56a442750fb5335a8e208ee77e275c7c2d217b11e11ad12915ceea49de2
6
+ metadata.gz: 6f2c6ee735c8135a86454cf69e08888e18f102dfdc75546c64afcbc00caba068edf90d8e3a5c284378314b60bc0762c68d12ef9a7bf00deea1be24992954c780
7
+ data.tar.gz: 6038c4e460cb1aa68ee140e6e464890fae548ea1e0c177ce9cda055826012da6fc002bf797d7a56385cdb65c9ae75be447d3c19da37c74f28e9faf06493ccd3a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- owners (0.0.9)
4
+ owners (0.1.0)
5
5
  thor
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -123,6 +123,14 @@ end
123
123
  OWNERS:7 => (?-mix:.env)
124
124
  ```
125
125
 
126
+ #### Finding files without owners
127
+
128
+ Stay on top of owner subscriptions by finding files that don't have any owners yet.
129
+
130
+ ```ruby
131
+ Owners.missing_for(".env", "some/other/file.rb") #=> ["some/other/file.rb"]
132
+ ```
133
+
126
134
  #### Git diff integration
127
135
 
128
136
  To find the owners for files changed with `git diff` use the `Owners.for_diff` method.
@@ -193,6 +201,7 @@ See `owners help` for more information.
193
201
  * `Owners.file=`
194
202
  * `Owners.for`
195
203
  * `Owners.for_diff`
204
+ * `Owners.missing_for`
196
205
  * `Owners::Owner#type`
197
206
  * `Owners::Owner#subscriptions`
198
207
  * `Owners::Subscription#file`
data/lib/owners.rb CHANGED
@@ -2,6 +2,7 @@ require "delegate"
2
2
  require "pathname"
3
3
  require "set"
4
4
  require "thor"
5
+ require "timeout"
5
6
  require_relative "owners/cli"
6
7
  require_relative "owners/config"
7
8
  require_relative "owners/owner"
@@ -28,7 +29,7 @@ module Owners
28
29
  #
29
30
  # @api public
30
31
  def for(*files)
31
- Search.new(files).results
32
+ Search.new(files).owners
32
33
  end
33
34
 
34
35
  # Accepts a git ref and an optional base ref and returns
@@ -50,7 +51,16 @@ module Owners
50
51
  hash.update(file => contents)
51
52
  end
52
53
 
53
- Search.new(files, configs).results
54
+ Search.new(files, configs).owners
55
+ end
56
+
57
+ # Accepts a list of file paths and returns an array of
58
+ # the ones that do not have subscribed owners.
59
+ #
60
+ # @api public
61
+ def missing_for(*files)
62
+ paths = Search.new(files, shallow: true).paths
63
+ files - paths
54
64
  end
55
65
  end
56
66
  end
data/lib/owners/cli.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  module Owners
2
2
  class CLI < Thor
3
+ include Timeout
4
+
3
5
  class_option :debug,
4
6
  aliases: %w(-d),
5
7
  desc: "Output additional subscription debugging info",
@@ -12,6 +14,8 @@ module Owners
12
14
 
13
15
  desc "for [FILES...]", "List owners for a set of files"
14
16
  def for(*files)
17
+ files = stdin_files unless files.any?
18
+
15
19
  Owners.file = options[:file] if options[:file]
16
20
  Owners.for(*files).each do |owner|
17
21
  output(owner)
@@ -26,6 +30,16 @@ module Owners
26
30
  end
27
31
  end
28
32
 
33
+ desc "missing_for [FILES...]", "List files that don't have owners"
34
+ def missing_for(*files)
35
+ files = stdin_files unless files.any?
36
+
37
+ Owners.file = options[:file] if options[:file]
38
+ Owners.missing_for(*files).each do |owner|
39
+ output(owner)
40
+ end
41
+ end
42
+
29
43
  no_commands do
30
44
  def output(owner)
31
45
  say owner
@@ -43,6 +57,12 @@ module Owners
43
57
  end
44
58
  end
45
59
  end
60
+
61
+ def stdin_files
62
+ timeout(1) { $stdin.read.split("\n") }
63
+ rescue Timeout::Error
64
+ []
65
+ end
46
66
  end
47
67
  end
48
68
  end
data/lib/owners/config.rb CHANGED
@@ -21,10 +21,11 @@ module Owners
21
21
  @root = File.dirname(@file)
22
22
  end
23
23
 
24
- def subscriptions(path)
24
+ def subscriptions(path, shallow)
25
25
  search do |subscription, results|
26
26
  if subscription.subscribed?(path)
27
27
  results << subscription
28
+ return results if shallow
28
29
  end
29
30
  end
30
31
  end
data/lib/owners/search.rb CHANGED
@@ -6,16 +6,23 @@ module Owners
6
6
  class Search
7
7
  RELATIVE = /^\.?\//
8
8
 
9
- def initialize(files, configs = nil)
9
+ def initialize(files, configs = nil, shallow: false)
10
10
  @files = files.map(&:dup)
11
11
  @configs = configs
12
+ @shallow = shallow
12
13
  end
13
14
 
14
- def results
15
- owners.each do |owner|
16
- subscriptions.each do |path, subscription|
17
- if subscription.subscribers.include?(owner)
18
- owner.subscriptions[path] << subscription
15
+ def paths
16
+ subscriptions_by_file.keys
17
+ end
18
+
19
+ def owners
20
+ subscribers.map do |subscriber|
21
+ Owner.new(subscriber).tap do |owner|
22
+ subscriptions.each do |path, subscription|
23
+ if subscription.subscribers.include?(owner)
24
+ owner.subscriptions[path] << subscription
25
+ end
19
26
  end
20
27
  end
21
28
  end
@@ -23,10 +30,6 @@ module Owners
23
30
 
24
31
  private
25
32
 
26
- def owners
27
- subscribers.map { |subscriber| Owner.new(subscriber) }
28
- end
29
-
30
33
  def subscribers
31
34
  subscriptions_by_file
32
35
  .values
@@ -44,7 +47,8 @@ module Owners
44
47
  def subscriptions_by_file
45
48
  search do |(path, config), results|
46
49
  relative = path.sub("./", "")
47
- results[relative] += config.subscriptions(path)
50
+ matches = config.subscriptions(path, @shallow)
51
+ results[relative] += matches if matches.any?
48
52
  end
49
53
  end
50
54
 
@@ -54,7 +58,7 @@ module Owners
54
58
  end
55
59
 
56
60
  def attempts
57
- paths.map(&:to_s).product(configs)
61
+ pathnames.map(&:to_s).product(configs)
58
62
  end
59
63
 
60
64
  def configs
@@ -66,10 +70,10 @@ module Owners
66
70
  end
67
71
 
68
72
  def trees
69
- paths.map { |path| Tree.new(path) }
73
+ pathnames.map { |path| Tree.new(path) }
70
74
  end
71
75
 
72
- def paths
76
+ def pathnames
73
77
  @files.map do |file|
74
78
  file.prepend("./") unless file =~ RELATIVE
75
79
  Pathname.new(file)
@@ -1,3 +1,3 @@
1
1
  module Owners
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,14 +1,17 @@
1
1
  RSpec.describe Owners::CLI do
2
- subject { capture { command } }
2
+ subject { capture(stdin) { command } }
3
3
 
4
4
  let(:command) { described_class.start(args) }
5
+ let(:stdin) { StringIO.new }
5
6
 
6
- def capture
7
+ def capture(stdin)
8
+ stdin, $stdin = $stdin, stdin
7
9
  stdout = $stdout
8
10
  $stdout = StringIO.new
9
11
  yield
10
12
  $stdout.string
11
13
  ensure
14
+ $stdin = stdin
12
15
  $stdout = stdout
13
16
  end
14
17
 
@@ -33,7 +36,7 @@ RSpec.describe Owners::CLI do
33
36
  end
34
37
  end
35
38
 
36
- context "without debugging" do
39
+ context "with debugging" do
37
40
  before { args << "-d" }
38
41
 
39
42
  it "parses owners correctly" do
@@ -53,6 +56,34 @@ group
53
56
  expect(subject).to eq(expected)
54
57
  end
55
58
  end
59
+
60
+ context "with stdin" do
61
+ let(:stdin) { StringIO.new("example/app/controllers/users_controller.rb") }
62
+
63
+ context "without paths" do
64
+ let(:args) { ["for"] }
65
+
66
+ it "reads paths from stdin" do
67
+ expect(subject).to eq("@org/auth\n@org/blog\n")
68
+ end
69
+ end
70
+
71
+ context "with paths" do
72
+ it "does not read paths from stdin" do
73
+ expect(subject).to eq("@org/auth\n@org/blog\n")
74
+ end
75
+ end
76
+
77
+ context "after timeout" do
78
+ let(:args) { ["for"] }
79
+ let(:stdin) { double("stdin") }
80
+
81
+ it "assumes no files were specified" do
82
+ expect(stdin).to receive(:read) { raise Timeout::Error }
83
+ expect(subject).to eq("")
84
+ end
85
+ end
86
+ end
56
87
  end
57
88
 
58
89
  describe "for_diff" do
@@ -76,4 +107,18 @@ group
76
107
  end
77
108
  end
78
109
  end
110
+
111
+ describe ".missing_for" do
112
+ context "with multiple paths" do
113
+ let(:args) {[
114
+ "missing_for",
115
+ "example/app/controllers/posts_controller.rb",
116
+ "path/without/owner.rb",
117
+ ]}
118
+
119
+ it "parses missing files missing owners correctly" do
120
+ expect(subject).to eq("path/without/owner.rb\n")
121
+ end
122
+ end
123
+ end
79
124
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: owners
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Huber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-02 00:00:00.000000000 Z
11
+ date: 2016-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec