wip: add commit-info command

This commit is contained in:
2021-04-26 00:23:14 +01:00
parent 9c977a75b5
commit 8d165b627b
10 changed files with 178 additions and 54 deletions

52
bin/commit-info Executable file
View File

@@ -0,0 +1,52 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'optparse'
require_relative '../lib/commit_info'
require_relative '../lib/errors'
require_relative '../lib/log'
options = {
repo: 'emacs-mirror/emacs',
output: File.expand_path('../tarballs', __dir__),
log_level: :info
}
OptionParser.new do |opts|
opts.banner = <<~TXT
Usage: ./commit-info [options] <branch/tag/sha>
Fetch commit info of given GitHub repository branch, tag, or SHA.
Options:
TXT
opts.on('-r', '--repo STRING',
"GitHub repository (default: #{options[:repo]})") do |v|
options[:repo] = v
end
opts.on('-o', '--output DIR', 'Directory to save tarball in ' \
"(default: #{options[:output]})") do |v|
options[:output] = v
end
opts.on('-l', '--log-level LEVEL', 'Log level ' \
"(default: #{options[:log_level]})") do |v|
options[:log_level] = v.to_sym
end
end.parse!
begin
logger = Log.new('commit-info', options[:log_level])
commit = CommitInfo.new(
ref: ARGV[0],
repo: options[:repo],
logger: logger
).perform
puts commit.to_yaml
rescue Error => e
handle_error(e)
end

View File

@@ -5,6 +5,7 @@ require 'optparse'
require_relative '../lib/download_tarball'
require_relative '../lib/errors'
require_relative '../lib/log'
options = {
repo: 'emacs-mirror/emacs',
@@ -38,7 +39,13 @@ OptionParser.new do |opts|
end.parse!
begin
tarball = DownloadTarball.new(ref: ARGV[0], **options).perform
logger = Log.new('download-tarball', options[:log_level])
tarball = DownloadTarball.new(
ref: ARGV[0],
repo: options[:repo],
output: options[:output],
logger: logger
).perform
puts tarball.to_yaml
rescue Error => e

9
lib/base_action.rb Normal file
View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
require_relative './common'
require_relative './output'
class BaseAction
include Common
include Output
end

View File

@@ -1,14 +1,27 @@
# frozen_string_literal: true
require 'json'
require 'time'
require 'yaml'
require_relative './errors'
require_relative './common'
class Commit
include Common
attr_reader :repo
attr_reader :ref
attr_reader :message
attr_reader :sha
attr_reader :time
def initialize(sha:, time:)
def initialize(sha:, time:, repo: nil, ref: nil, message: nil)
@sha = sha
@time = time
@repo = repo
@ref = ref
@message = message
end
def sha_short
@@ -17,9 +30,13 @@ class Commit
def to_hash
{
'repo' => repo,
'ref' => ref,
'sha' => sha,
'sha_short' => sha_short,
'time' => time
'time' => time.utc,
'timestamp' => time.utc.to_i,
'message' => message
}
end

43
lib/commit_info.rb Normal file
View File

@@ -0,0 +1,43 @@
# frozen_string_literal: true
require_relative './base_action'
require_relative './commit'
class CommitInfo < BaseAction
COMMIT_URL = 'https://api.github.com/repos/%s/commits/%s'
attr_reader :ref
attr_reader :repo
attr_reader :logger
def initialize(ref:, repo:, logger:)
@ref = ref
@repo = repo
@logger = logger
err 'branch/tag/sha argument cannot be empty' if ref.nil? || ref.empty?
end
def perform
info "Fetching info for git ref: #{ref}"
url = format(COMMIT_URL, repo, ref)
commit_json = http_get(url)
err "Failed to get commit info about: #{ref}" if commit_json.nil?
parsed = JSON.parse(commit_json)
commit = Commit.new(
repo: repo,
ref: ref,
sha: parsed&.dig('sha'),
message: parsed&.dig('commit', 'message'),
time: Time.parse(parsed&.dig('commit', 'committer', 'date')).utc
)
err 'Failed to get commit SHA' if commit.sha.nil? || commit.sha.empty?
err 'Failed to get commit time' if commit.time.nil?
commit
end
end

View File

@@ -5,6 +5,10 @@ require 'net/http'
module Common
private
def self.included(base)
base.extend(self)
end
def run_cmd(*args)
info "executing: #{args.join(' ')}"
system(*args) || err("Exit code: #{$CHILD_STATUS.exitstatus}")

View File

@@ -4,30 +4,24 @@ require 'fileutils'
require 'json'
require 'time'
require_relative './common'
require_relative './commit'
require_relative './output'
require_relative './base_action'
require_relative './commit_info'
require_relative './tarball'
class DownloadTarball
include Common
include Output
logger_name 'download-tarball'
class DownloadTarball < BaseAction
TARBALL_URL = 'https://github.com/%s/tarball/%s'
COMMIT_URL = 'https://api.github.com/repos/%s/commits/%s'
attr_reader :ref
attr_reader :repo
attr_reader :output
attr_reader :log_level
attr_reader :logger
def initialize(ref:, repo:, output:, log_level:)
def initialize(ref:, repo:, output:, logger:)
@ref = ref
@repo = repo
@output = output
@log_level = log_level
@logger = logger
err 'branch/tag/sha argument cannot be empty' if ref.nil? || ref.empty?
end
@@ -62,22 +56,6 @@ class DownloadTarball
end
def commit
return @commit if @commit
info "Fetching info for git ref: #{ref}"
url = format(COMMIT_URL, repo, ref)
commit_json = http_get(url)
err "Failed to get commit info about: #{ref}" if commit_json.nil?
parsed = JSON.parse(commit_json)
commit = Commit.new(
sha: parsed&.dig('sha'),
time: Time.parse(parsed&.dig('commit', 'committer', 'date'))
)
err 'Failed to get commit SHA' if commit.sha.nil? || commit.sha.empty?
err 'Failed to get commit time' if commit.time.nil?
@commit = commit
@commit ||= CommitInfo.new(ref: ref, repo: repo, logger: logger).perform
end
end

View File

@@ -6,3 +6,7 @@ def handle_error(err)
end
class Error < StandardError; end
class CommitNotFound < Error; end
class NoCommitSHA < Error; end
class NoCommitTime < Error; end

31
lib/log.rb Normal file
View File

@@ -0,0 +1,31 @@
# frozen_string_literal: true
class Log
extend Forwardable
attr_reader :name
attr_reader :level
def initialize(name, level = :info)
@name = name
@level = level
end
def_delegators :logger, :debug, :info, :warn, :error, :fatal, :unkonwn
private
def logger
@logger ||= Logger.new($stderr).tap do |l|
l.progname = name
l.level = level
l.formatter = formatter
end
end
def formatter
proc do |severity, _datetime, progname, msg|
"==> [#{progname}] #{severity}: #{msg}\n"
end
end
end

View File

@@ -25,25 +25,4 @@ module Output
def err(msg = nil)
raise Error, msg
end
private
# override to set custom log level
def log_level
:info
end
def logger
@logger ||= Logger.new($stderr).tap do |l|
l.progname = self.class.logger_name
l.level = log_level
l.formatter = log_formatter
end
end
def log_formatter
proc do |severity, _datetime, progname, msg|
"==> [#{progname}] #{severity}: #{msg}\n"
end
end
end