Class: Jackal::CodeFetcher::GitHub

Inherits:
Callback
  • Object
show all
Defined in:
lib/jackal-code-fetcher/git_hub.rb

Overview

GitHub code fetcher

Instance Method Summary collapse

Instance Method Details

#delete_repository(payload) ⇒ TrueClass, FalseClass

Delete local repository path

Parameters:

  • payload (Smash)

Returns:

  • (TrueClass, FalseClass)


87
88
89
90
91
92
93
94
95
96
# File 'lib/jackal-code-fetcher/git_hub.rb', line 87

def delete_repository(payload)
  path = repository_path(payload)
  if(File.exists?(path))
    warn "Deleting repository directory: #{path}"
    FileUtils.rm_rf(path)
    true
  else
    false
  end
end

#execute(message) ⇒ Object

Fetch code and push to asset store

Parameters:

  • message (Carnivore::Message)


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/jackal-code-fetcher/git_hub.rb', line 37

def execute(message)
  failure_wrap(message) do |payload|
    retried = false
    locked = lock_repo(payload)
    begin
      store_reference(payload)
    rescue Git::GitExecuteError => e
      unless(retried)
        retried = true
        delete_repository(payload)
        error "Reference extraction from repository failed. Repository deleted and retrying. (Error: #{e.class} - #{e})"
        retry
      else
        raise
      end
    ensure
      unlock_repo(locked)
    end
    job_completed(:code_fetcher, payload, message)
  end
end

#fetch_repository(payload) ⇒ String

Fetch repository from GitHub

Parameters:

  • payload (Smash)

Returns:

  • (String)

    path to repository directory



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/jackal-code-fetcher/git_hub.rb', line 140

def fetch_repository(payload)
  repo_path = repository_path(payload)
  if(File.directory?(repo_path))
    debug "Pulling changes to: #{repo_path}"
    repo = Git.open(repo_path)
    repo.checkout('master')
    repo.pull
    repo.fetch
  else
    debug "Initiating repository clone to: #{repo_path}"
    Git.clone(github_url(payload), repo_path)
  end
  repo_path
end

#github_url(payload) ⇒ String

Build github URL for fetching

Parameters:

  • payload (Smash)

Returns:

  • (String)


112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/jackal-code-fetcher/git_hub.rb', line 112

def github_url(payload)
  if(payload.get(:data, :code_fetcher, :info, :private))
    uri = URI.parse(payload.get(:data, :code_fetcher, :info, :url))
    uri.scheme = 'https'
    uri.user = config.fetch(:github, :access_token,
      app_config.get(:github, :access_token)
    )
    uri.to_s
  else
    payload.get(:data, :code_fetcher, :info, :url)
  end
end

#lock_repo(payload) ⇒ File

Lock repository via lock file

Parameters:

  • payload (Smash)

Returns:

  • (File)


63
64
65
66
67
68
69
70
71
72
# File 'lib/jackal-code-fetcher/git_hub.rb', line 63

def lock_repo(payload)
  lock_path = File.join(
    working_directory,
    "#{payload.get(:data, :code_fetcher, :info, :owner)}-" <<
    "#{payload.get(:data, :code_fetcher, :info, :name)}.lock"
  )
  lock_file = File.open(lock_path, 'w')
  lock_file.flock(File::LOCK_EX)
  lock_file
end

#pack_and_store(path, payload) ⇒ TrueClass

Store reference in asset store

Parameters:

  • path (String)

    local path to repository

  • payload (Smash)

Returns:

  • (TrueClass)


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/jackal-code-fetcher/git_hub.rb', line 160

def pack_and_store(path, payload)
  repo = Git.open(path)
  repo.checkout(
    payload.get(:data, :code_fetcher, :info, :commit_sha)
  )
  asset_key = [
    payload.get(:data, :code_fetcher, :info, :owner),
    payload.get(:data, :code_fetcher, :info, :name),
    payload.get(:data, :code_fetcher, :info, :commit_sha)
  ].join('-') + '.zip'
  _path = File.join(working_directory, Celluloid.uuid)
  begin
    tmp_path = File.join(_path, asset_key)
    FileUtils.mkdir_p(tmp_path)
    FileUtils.cp_r(File.join(repository_path(payload), '.'), tmp_path)
    FileUtils.rm_rf(File.join(tmp_path, '.git'))
    tarball = asset_store.pack(tmp_path)
    asset_store.put(asset_key, tarball)
  ensure
    FileUtils.rm_rf(_path)
  end
  payload.set(:data, :code_fetcher, :asset, asset_key)
  true
end

#repository_path(payload) ⇒ String

Generate local path

Returns:

  • (String)

    path



128
129
130
131
132
133
134
# File 'lib/jackal-code-fetcher/git_hub.rb', line 128

def repository_path(payload)
  File.join(
    working_directory,
    payload.get(:data, :code_fetcher, :info, :owner),
    payload.get(:data, :code_fetcher, :info, :name)
  )
end

#setup(*_) ⇒ Object

Setup callback



9
10
11
12
13
# File 'lib/jackal-code-fetcher/git_hub.rb', line 9

def setup(*_)
  require 'uri'
  require 'git'
  require 'fileutils'
end

#store_reference(payload) ⇒ TrueClass

Fetch reference from GitHub repository and store compressed copy in the asset store

Parameters:

  • payload (Smash)

Returns:

  • (TrueClass)


103
104
105
106
# File 'lib/jackal-code-fetcher/git_hub.rb', line 103

def store_reference(payload)
  repo_dir = fetch_repository(payload)
  pack_and_store(repo_dir, payload)
end

#unlock_repo(lock_file) ⇒ File

Unlock the repository via lock file

Parameters:

  • lock_file (File)

Returns:

  • (File)


78
79
80
81
# File 'lib/jackal-code-fetcher/git_hub.rb', line 78

def unlock_repo(lock_file)
  lock_file.close
  lock_file
end

#valid?(message) ⇒ Truthy, Falsey

Determine validity of message

Parameters:

  • message (Carnivore::Message)

Returns:

  • (Truthy, Falsey)


27
28
29
30
31
32
# File 'lib/jackal-code-fetcher/git_hub.rb', line 27

def valid?(message)
  super do |payload|
    payload.get(:data, :code_fetcher, :info, :commit_sha) &&
      !payload.get(:data, :code_fetcher, :asset)
  end
end

#working_directoryString

Returns working directory.

Returns:

  • (String)

    working directory



16
17
18
19
20
21
# File 'lib/jackal-code-fetcher/git_hub.rb', line 16

def working_directory
  memoize(:working_directory, :direct) do
    FileUtils.mkdir_p(path = config.fetch(:working_directory, '/tmp/jackal-code-fetcher'))
    path
  end
end