Commit 37f0b600bc9a994136791e6838b3228c56f909b2
1 parent
94af622c
Exists in
master
and in
4 other branches
Another RefExtractor refactor
Showing
2 changed files
with
83 additions
and
58 deletions
Show diff stats
lib/ref_extractor.rb
1 | 1 | # Module providing an extract_ref method for controllers working with Git |
2 | 2 | # tree-ish + path params |
3 | -# | |
4 | -# Given a string containing both a Git ref - such as a branch or tag - and a | |
5 | -# filesystem path joined by forward slashes, attempts to separate the two. | |
6 | -# | |
7 | -# Expects a @project instance variable to contain the active project. Used to | |
8 | -# check the input against a list of valid repository refs. | |
9 | -# | |
10 | -# Examples | |
11 | -# | |
12 | -# # No @project available | |
13 | -# extract_ref('master') | |
14 | -# # => ['', ''] | |
15 | -# | |
16 | -# extract_ref('master') | |
17 | -# # => ['master', '/'] | |
18 | -# | |
19 | -# extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG") | |
20 | -# # => ['f4b14494ef6abf3d144c28e4af0c20143383e062', '/CHANGELOG'] | |
21 | -# | |
22 | -# extract_ref("v2.0.0/README.md") | |
23 | -# # => ['v2.0.0', '/README.md'] | |
24 | -# | |
25 | -# extract_ref('issues/1234/app/models/project.rb') | |
26 | -# # => ['issues/1234', '/app/models/project.rb'] | |
27 | -# | |
28 | -# # Given an invalid branch, we fall back to just splitting on the first slash | |
29 | -# extract_ref('non/existent/branch/README.md') | |
30 | -# # => ['non', '/existent/branch/README.md'] | |
31 | -# | |
32 | -# Returns an Array where the first value is the tree-ish and the second is the | |
33 | -# path | |
34 | 3 | module RefExtractor |
4 | + # Thrown when given an invalid path | |
5 | + class InvalidPathError < StandardError; end | |
6 | + | |
7 | + # Given a string containing both a Git ref - such as a branch or tag - and a | |
8 | + # filesystem path joined by forward slashes, attempts to separate the two. | |
9 | + # | |
10 | + # Expects a @project instance variable to contain the active project. Used to | |
11 | + # check the input against a list of valid repository refs. | |
12 | + # | |
13 | + # Examples | |
14 | + # | |
15 | + # # No @project available | |
16 | + # extract_ref('master') | |
17 | + # # => ['', ''] | |
18 | + # | |
19 | + # extract_ref('master') | |
20 | + # # => ['master', ''] | |
21 | + # | |
22 | + # extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG") | |
23 | + # # => ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG'] | |
24 | + # | |
25 | + # extract_ref("v2.0.0/README.md") | |
26 | + # # => ['v2.0.0', 'README.md'] | |
27 | + # | |
28 | + # extract_ref('issues/1234/app/models/project.rb') | |
29 | + # # => ['issues/1234', 'app/models/project.rb'] | |
30 | + # | |
31 | + # # Given an invalid branch, we fall back to just splitting on the first slash | |
32 | + # extract_ref('non/existent/branch/README.md') | |
33 | + # # => ['non', 'existent/branch/README.md'] | |
34 | + # | |
35 | + # Returns an Array where the first value is the tree-ish and the second is the | |
36 | + # path | |
35 | 37 | def extract_ref(input) |
36 | 38 | pair = ['', ''] |
37 | 39 | |
... | ... | @@ -41,24 +43,28 @@ module RefExtractor |
41 | 43 | # If the ref appears to be a SHA, we're done, just split the string |
42 | 44 | pair = $~.captures |
43 | 45 | else |
46 | + # Otherwise, attempt to detect the ref using a list of the project's | |
47 | + # branches and tags | |
48 | + | |
44 | 49 | # Append a trailing slash if we only get a ref and no file path |
45 | 50 | id = input |
46 | 51 | id += '/' unless id.include?('/') |
47 | 52 | |
48 | - # Otherwise, attempt to detect the ref using a list of the project's | |
49 | - # branches and tags | |
50 | 53 | valid_refs = @project.branches + @project.tags |
51 | 54 | valid_refs.select! { |v| id.start_with?("#{v}/") } |
52 | 55 | |
53 | 56 | if valid_refs.length != 1 |
54 | 57 | # No exact ref match, so just try our best |
55 | - pair = id.match(/([^\/]+)(.+)/).captures | |
58 | + pair = id.match(/([^\/]+)(.*)/).captures | |
56 | 59 | else |
57 | 60 | # Partition the string into the ref and the path, ignoring the empty first value |
58 | 61 | pair = id.partition(valid_refs.first)[1..-1] |
59 | 62 | end |
60 | 63 | end |
61 | 64 | |
65 | + # Remove leading slash from path | |
66 | + pair[1].gsub!(/^\//, '') | |
67 | + | |
62 | 68 | pair |
63 | 69 | end |
64 | 70 | end | ... | ... |
spec/lib/ref_extractor_spec.rb
... | ... | @@ -11,29 +11,48 @@ describe RefExtractor do |
11 | 11 | project.stub(:tags).and_return(['v1.0.0', 'v2.0.0']) |
12 | 12 | end |
13 | 13 | |
14 | - it "extracts a ref without a path" do | |
15 | - extract_ref('master').should == ['master', '/'] | |
16 | - end | |
17 | - | |
18 | - it "extracts a valid branch ref" do | |
19 | - extract_ref('foo/bar/baz/CHANGELOG').should == ['foo/bar/baz', '/CHANGELOG'] | |
20 | - end | |
21 | - | |
22 | - it "extracts a valid tag ref" do | |
23 | - extract_ref('v2.0.0/CHANGELOG').should == ['v2.0.0', '/CHANGELOG'] | |
24 | - end | |
25 | - | |
26 | - it "extracts a valid commit ref" do | |
27 | - extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG').should == | |
28 | - ['f4b14494ef6abf3d144c28e4af0c20143383e062', '/CHANGELOG'] | |
29 | - end | |
30 | - | |
31 | - it "falls back to a primitive split for an invalid ref" do | |
32 | - extract_ref('stable/CHANGELOG').should == ['stable', '/CHANGELOG'] | |
33 | - end | |
34 | - | |
35 | - it "returns an empty pair when no @project is set" do | |
36 | - @project = nil | |
37 | - extract_ref('master/CHANGELOG').should == ['', ''] | |
14 | + describe '#extract_ref' do | |
15 | + it "returns an empty pair when no @project is set" do | |
16 | + @project = nil | |
17 | + extract_ref('master/CHANGELOG').should == ['', ''] | |
18 | + end | |
19 | + | |
20 | + context "without a path" do | |
21 | + it "extracts a valid branch" do | |
22 | + extract_ref('master').should == ['master', ''] | |
23 | + end | |
24 | + | |
25 | + it "extracts a valid tag" do | |
26 | + extract_ref('v2.0.0').should == ['v2.0.0', ''] | |
27 | + end | |
28 | + | |
29 | + it "extracts a valid commit ref without a path" do | |
30 | + extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062').should == | |
31 | + ['f4b14494ef6abf3d144c28e4af0c20143383e062', ''] | |
32 | + end | |
33 | + | |
34 | + it "falls back to a primitive split for an invalid ref" do | |
35 | + extract_ref('stable').should == ['stable', ''] | |
36 | + end | |
37 | + end | |
38 | + | |
39 | + context "with a path" do | |
40 | + it "extracts a valid branch" do | |
41 | + extract_ref('foo/bar/baz/CHANGELOG').should == ['foo/bar/baz', 'CHANGELOG'] | |
42 | + end | |
43 | + | |
44 | + it "extracts a valid tag" do | |
45 | + extract_ref('v2.0.0/CHANGELOG').should == ['v2.0.0', 'CHANGELOG'] | |
46 | + end | |
47 | + | |
48 | + it "extracts a valid commit SHA" do | |
49 | + extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG').should == | |
50 | + ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG'] | |
51 | + end | |
52 | + | |
53 | + it "falls back to a primitive split for an invalid ref" do | |
54 | + extract_ref('stable/CHANGELOG').should == ['stable', 'CHANGELOG'] | |
55 | + end | |
56 | + end | |
38 | 57 | end |
39 | 58 | end | ... | ... |