owners 0.0.9 → 0.1.0

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
  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