Class: Ra10ke::GitRepo

Inherits:
Object
  • Object
show all
Defined in:
lib/ra10ke/git_repo.rb

Constant Summary collapse

REMOTE_REFS_CMD =
'git ls-remote --symref'
CLONE_CMD =
'git clone --no-tags'
CURRENT_BRANCH_CMD =
'git symbolic-ref --short HEAD'
SHOW_CMD =
'git show'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url) ⇒ GitRepo

Returns a new instance of GitRepo.



14
15
16
# File 'lib/ra10ke/git_repo.rb', line 14

def initialize(url)
  @url = url
end

Instance Attribute Details

#urlObject (readonly)

Returns the value of attribute url.



7
8
9
# File 'lib/ra10ke/git_repo.rb', line 7

def url
  @url
end

Class Method Details

.current_branch(path) ⇒ String

Get the current branch for a Git repo

Parameters:

  • path (String)
    • The path to the repository to check

Returns:

  • (String)
    • The current active branch of the Git repo



21
22
23
24
25
26
# File 'lib/ra10ke/git_repo.rb', line 21

def self.current_branch(path)
  Dir.chdir(path) do
    data, success = run_command(CURRENT_BRANCH_CMD)
    return success ? data.strip : nil
  end
end

.run_command(cmd, silent: false) ⇒ Array

useful for mocking easily

Parameters:

  • cmd (String)
  • silent (Boolean) (defaults to: false)

    set to true if you wish to send output to /dev/null, false by default

Returns:

  • (Array)


117
118
119
120
121
# File 'lib/ra10ke/git_repo.rb', line 117

def self.run_command(cmd, silent: false)
  out_args = silent ? '2>&1 > /dev/null' : '2>&1'
  out = `#{cmd} #{out_args}`
  [out, $CHILD_STATUS.success?]
end

Instance Method Details

#all_refsArray

Returns - an array of all the refs associated with the remote repository.

Examples:

[{:sha=>"0ec707e431367bbe2752966be8ab915b6f0da754", :ref=>"refs/heads/74110ac", :type=>:branch, :subtype=>nil, :name=>"74110ac"},
  :sha=>"07bb5d2d94db222dca5860eb29c184e8970f36f4", :ref=>"refs/pull/74/head", :type=>:pull, :subtype=>:head, :name=>"74"},
  :sha=>"156ca9a8ea69e056e86355b27d944e59d1b3a1e1", :ref=>"refs/heads/master", :type=>:branch, :subtype=>nil, :name=>"master"},
  :sha=>"fcc0532bbc5a5b65f3941738339e9cc7e3d767ce", :ref=>"refs/pull/249/head", :type=>:pull, :subtype=>:head, :name=>"249"},
  :sha=>"8d54891fa5df75890ee15d53080c2a81b4960f92", :ref=>"refs/pull/267/head", :type=>:pull, :subtype=>:head, :name=>"267"}]

Parameters:

  • url (String)
    • the git string either https or ssh url

Returns:

  • (Array)
    • an array of all the refs associated with the remote repository



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/ra10ke/git_repo.rb', line 84

def all_refs
  @all_refs ||= remote_refs.each_with_object([]) do |line, refs|
    sha, ref = line.split("\t")
    next refs if line.include?('redirecting')
    next refs if sha.eql?('ref: refs/heads/master')

    _, type, name, subtype = ref.chomp.split('/')
    next refs unless name

    type = :tag if type.eql?('tags')
    type = type.to_sym
    subtype = subtype.to_sym if subtype
    type = :branch if type.eql?(:heads)
    refs << { sha: sha, ref: ref.chomp, type: type, subtype: subtype, name: name }
  end
end

#get_ref_like(ref_name) ⇒ String

Returns the matching ref_name or nil.

Parameters:

Returns:

  • (String)

    the matching ref_name or nil



105
106
107
108
109
110
111
# File 'lib/ra10ke/git_repo.rb', line 105

def get_ref_like(ref_name)
  return nil unless valid_url?

  all_refs.find do |ref|
    ref[:name].include?(ref_name)
  end
end

#remote_refsArray

return empty array if url or command failed

Returns:

  • (Array)
    • the raw data from the git ls-remote command as lines array



30
31
32
33
34
35
# File 'lib/ra10ke/git_repo.rb', line 30

def remote_refs
  @remote_refs ||= begin
    data, success = run_command("#{REMOTE_REFS_CMD} #{url}")
    success ? data.lines : []
  end
end

#run_command(cmd, silent: false) ⇒ Object



123
124
125
# File 'lib/ra10ke/git_repo.rb', line 123

def run_command(cmd, silent: false)
  self.class.run_command(cmd, silent: silent)
end

#valid_commit?(sha) ⇒ Boolean

Returns - return true if the commit sha is valid.

Parameters:

  • url (String)
    • the git string either https or ssh url

  • ref (String)
    • the sha id

Returns:

  • (Boolean)
    • return true if the commit sha is valid



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ra10ke/git_repo.rb', line 45

def valid_commit?(sha)
  return false if sha.nil? || sha.empty?
  return true if valid_ref?(sha)

  # cloning is a last resort if for some reason we cannot
  # remotely get via ls-remote
  Dir.mktmpdir do |dir|
    run_command("#{CLONE_CMD} #{url} #{dir}", silent: true)
    Dir.chdir(dir) do
      _, status = run_command("#{SHOW_CMD} #{sha}", silent: true)
      status
    end
  end
end

#valid_ref?(ref = 'HEAD') ⇒ Boolean

Returns - return true if the ref is valid.

Parameters:

  • url (String)
    • the git string either https or ssh url

  • ref (String) (defaults to: 'HEAD')
    • the ref object, branch name, tag name, or commit sha, defaults to HEAD

Returns:

  • (Boolean)
    • return true if the ref is valid



63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/ra10ke/git_repo.rb', line 63

def valid_ref?(ref = 'HEAD')
  return false if ref.nil?

  found = all_refs.find do |data|
    # we don't need to bother with these types
    next if data[:type] == :pull || data[:type] == :merge_request

    # is the name equal to the tag or branch?  Is the commit sha equal?
    data[:name].eql?(ref) || data[:sha].slice(0, 8).eql?(ref.slice(0, 8))
  end
  !found.nil?
end

#valid_url?Boolean

Returns true if the git url is valid.

Returns:

  • (Boolean)

    true if the git url is valid



38
39
40
# File 'lib/ra10ke/git_repo.rb', line 38

def valid_url?
  !remote_refs.empty?
end