Skip to content
Snippets Groups Projects
Commit 37f0b600 authored by Robert Speicher's avatar Robert Speicher
Browse files

Another RefExtractor refactor

parent 94af622c
No related branches found
No related tags found
No related merge requests found
# Module providing an extract_ref method for controllers working with Git # Module providing an extract_ref method for controllers working with Git
# tree-ish + path params # tree-ish + path params
#
# Given a string containing both a Git ref - such as a branch or tag - and a
# filesystem path joined by forward slashes, attempts to separate the two.
#
# Expects a @project instance variable to contain the active project. Used to
# check the input against a list of valid repository refs.
#
# Examples
#
# # No @project available
# extract_ref('master')
# # => ['', '']
#
# extract_ref('master')
# # => ['master', '/']
#
# extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG")
# # => ['f4b14494ef6abf3d144c28e4af0c20143383e062', '/CHANGELOG']
#
# extract_ref("v2.0.0/README.md")
# # => ['v2.0.0', '/README.md']
#
# extract_ref('issues/1234/app/models/project.rb')
# # => ['issues/1234', '/app/models/project.rb']
#
# # Given an invalid branch, we fall back to just splitting on the first slash
# extract_ref('non/existent/branch/README.md')
# # => ['non', '/existent/branch/README.md']
#
# Returns an Array where the first value is the tree-ish and the second is the
# path
module RefExtractor module RefExtractor
# Thrown when given an invalid path
class InvalidPathError < StandardError; end
# Given a string containing both a Git ref - such as a branch or tag - and a
# filesystem path joined by forward slashes, attempts to separate the two.
#
# Expects a @project instance variable to contain the active project. Used to
# check the input against a list of valid repository refs.
#
# Examples
#
# # No @project available
# extract_ref('master')
# # => ['', '']
#
# extract_ref('master')
# # => ['master', '']
#
# extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG")
# # => ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
#
# extract_ref("v2.0.0/README.md")
# # => ['v2.0.0', 'README.md']
#
# extract_ref('issues/1234/app/models/project.rb')
# # => ['issues/1234', 'app/models/project.rb']
#
# # Given an invalid branch, we fall back to just splitting on the first slash
# extract_ref('non/existent/branch/README.md')
# # => ['non', 'existent/branch/README.md']
#
# Returns an Array where the first value is the tree-ish and the second is the
# path
def extract_ref(input) def extract_ref(input)
pair = ['', ''] pair = ['', '']
   
Loading
@@ -41,24 +43,28 @@ module RefExtractor
Loading
@@ -41,24 +43,28 @@ module RefExtractor
# If the ref appears to be a SHA, we're done, just split the string # If the ref appears to be a SHA, we're done, just split the string
pair = $~.captures pair = $~.captures
else else
# Otherwise, attempt to detect the ref using a list of the project's
# branches and tags
# Append a trailing slash if we only get a ref and no file path # Append a trailing slash if we only get a ref and no file path
id = input id = input
id += '/' unless id.include?('/') id += '/' unless id.include?('/')
   
# Otherwise, attempt to detect the ref using a list of the project's
# branches and tags
valid_refs = @project.branches + @project.tags valid_refs = @project.branches + @project.tags
valid_refs.select! { |v| id.start_with?("#{v}/") } valid_refs.select! { |v| id.start_with?("#{v}/") }
   
if valid_refs.length != 1 if valid_refs.length != 1
# No exact ref match, so just try our best # No exact ref match, so just try our best
pair = id.match(/([^\/]+)(.+)/).captures pair = id.match(/([^\/]+)(.*)/).captures
else else
# Partition the string into the ref and the path, ignoring the empty first value # Partition the string into the ref and the path, ignoring the empty first value
pair = id.partition(valid_refs.first)[1..-1] pair = id.partition(valid_refs.first)[1..-1]
end end
end end
   
# Remove leading slash from path
pair[1].gsub!(/^\//, '')
pair pair
end end
end end
Loading
@@ -11,29 +11,48 @@ describe RefExtractor do
Loading
@@ -11,29 +11,48 @@ describe RefExtractor do
project.stub(:tags).and_return(['v1.0.0', 'v2.0.0']) project.stub(:tags).and_return(['v1.0.0', 'v2.0.0'])
end end
   
it "extracts a ref without a path" do describe '#extract_ref' do
extract_ref('master').should == ['master', '/'] it "returns an empty pair when no @project is set" do
end @project = nil
extract_ref('master/CHANGELOG').should == ['', '']
it "extracts a valid branch ref" do end
extract_ref('foo/bar/baz/CHANGELOG').should == ['foo/bar/baz', '/CHANGELOG']
end context "without a path" do
it "extracts a valid branch" do
it "extracts a valid tag ref" do extract_ref('master').should == ['master', '']
extract_ref('v2.0.0/CHANGELOG').should == ['v2.0.0', '/CHANGELOG'] end
end
it "extracts a valid tag" do
it "extracts a valid commit ref" do extract_ref('v2.0.0').should == ['v2.0.0', '']
extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG').should == end
['f4b14494ef6abf3d144c28e4af0c20143383e062', '/CHANGELOG']
end it "extracts a valid commit ref without a path" do
extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062').should ==
it "falls back to a primitive split for an invalid ref" do ['f4b14494ef6abf3d144c28e4af0c20143383e062', '']
extract_ref('stable/CHANGELOG').should == ['stable', '/CHANGELOG'] end
end
it "falls back to a primitive split for an invalid ref" do
it "returns an empty pair when no @project is set" do extract_ref('stable').should == ['stable', '']
@project = nil end
extract_ref('master/CHANGELOG').should == ['', ''] end
context "with a path" do
it "extracts a valid branch" do
extract_ref('foo/bar/baz/CHANGELOG').should == ['foo/bar/baz', 'CHANGELOG']
end
it "extracts a valid tag" do
extract_ref('v2.0.0/CHANGELOG').should == ['v2.0.0', 'CHANGELOG']
end
it "extracts a valid commit SHA" do
extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG').should ==
['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
end
it "falls back to a primitive split for an invalid ref" do
extract_ref('stable/CHANGELOG').should == ['stable', 'CHANGELOG']
end
end
end end
end end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment