Module: Gitx::Github

Included in:
Cli::IntegrateCommand, Cli::ReleaseCommand, Cli::ReviewCommand
Defined in:
lib/gitx/github.rb

Constant Summary collapse

GLOBAL_CONFIG_FILE =
'~/.config/gitx/github.yml'.freeze
REVIEW_CONTEXT =
'peer_review'.freeze
CLIENT_URL =
'https://github.com/wireframe/gitx'.freeze
<<-MESSAGE.dedent
  # Pull Request Protips(tm):
  # * Describe how this change accomplishes the task at hand
  # * Use GitHub flavored Markdown http://github.github.com/github-flavored-markdown/
  # * Include links to relevent resources and related tickets
  # * Attach build artifacts, images, screenshots, screencasts, etc
  # * Review CONTRIBUTING.md for relevant workflow requirements
  #
  # This footer will automatically be stripped from the pull request description
MESSAGE
PULL_REQEST_TEMPLATE_FILE =
'.github/PULL_REQUEST_TEMPLATE.md'

Instance Method Summary collapse

Instance Method Details

#ask_without_echo(message) ⇒ Object



174
175
176
177
178
# File 'lib/gitx/github.rb', line 174

def ask_without_echo(message)
  value = ask(message, echo: false)
  say ''
  value
end

#authorization_tokenString

authorization token used for github API calls the token is cached on the filesystem for future use

Returns:

  • (String)

    auth token stored in git (current repo, user config or installed global settings)

See Also:



108
109
110
111
112
113
114
115
116
# File 'lib/gitx/github.rb', line 108

def authorization_token
  auth_token = ENV['GITX_GITHUB_TOKEN'] || global_config['token']
  auth_token ||= begin
    new_token = fetch_token
    save_global_config('token' => new_token)
    new_token
  end
  auth_token
end

#branch_status(branch) ⇒ Object

Get the current commit status of a branch



50
51
52
53
# File 'lib/gitx/github.rb', line 50

def branch_status(branch)
  response = github_client.status(github_slug, branch)
  response.state
end

#create_pull_request(branch) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/gitx/github.rb', line 66

def create_pull_request(branch)
  say 'Creating pull request for '
  say "#{branch} ", :green
  say 'against '
  say "#{config.base_branch} ", :green
  say 'in '
  say github_slug, :green

  title = pull_request_title(branch)
  body = pull_request_body(branch)
  github_client.create_pull_request(github_slug, config.base_branch, branch, title, body)
end

#fetch_tokenObject



118
119
120
# File 'lib/gitx/github.rb', line 118

def fetch_token
  ask_without_echo("Github personal access token with repo scopes for #{username}: ")
end

#find_or_create_pull_request(branch) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/gitx/github.rb', line 22

def find_or_create_pull_request(branch)
  pull_request = find_pull_request(branch)
  pull_request ||= begin
    checkout_branch(branch)
    run_git_cmd 'update'
    pull_request = create_pull_request(branch)
    say 'Created pull request: '
    say pull_request.html_url, :green

    pull_request
  end
  pull_request
end

#find_pull_request(branch) ⇒ Sawyer::Resource

Returns:

  • (Sawyer::Resource)

    data structure of pull request info if found

  • nil if no pull request found



38
39
40
41
42
43
44
45
46
# File 'lib/gitx/github.rb', line 38

def find_pull_request(branch)
  head_reference = "#{github_organization}:#{branch}"
  params = {
    head: head_reference,
    state: 'open'
  }
  pull_requests = github_client.pull_requests(github_slug, params)
  pull_requests.first
end

#github_clientObject



127
128
129
# File 'lib/gitx/github.rb', line 127

def github_client
  @github_client ||= Octokit::Client.new(access_token: authorization_token)
end

#github_client_nameObject



122
123
124
125
# File 'lib/gitx/github.rb', line 122

def github_client_name
  timestamp = Time.now.utc.strftime('%FT%R:%S%z')
  "Git eXtensions #{timestamp}"
end

#github_organizationObject



150
151
152
# File 'lib/gitx/github.rb', line 150

def github_organization
  github_slug.split('/').first
end

#github_slugObject

Returns the github slug for the current repository’s remote origin url.

Examples:

git@github.com:socialcast/wireframe/gitx.git #=> wireframe/gitx
https://github.com/wireframe/gitx.git #=> wireframe/gitx

Returns:

  • the github slug for the current repository’s remote origin url.



145
146
147
148
# File 'lib/gitx/github.rb', line 145

def github_slug
  remote = repo.config['remote.origin.url']
  remote.to_s.gsub(/\.git$/, '').split(%r{[:/]}).last(2).join('/')
end

#global_configObject



158
159
160
# File 'lib/gitx/github.rb', line 158

def global_config
  @global_config ||= File.exist?(global_config_file) ? YAML.load_file(global_config_file) : {}
end

#global_config_fileObject



154
155
156
# File 'lib/gitx/github.rb', line 154

def global_config_file
  File.expand_path(GLOBAL_CONFIG_FILE)
end

#label_pull_request(pull_request, label) ⇒ Object



61
62
63
# File 'lib/gitx/github.rb', line 61

def label_pull_request(pull_request, label)
  github_client.add_labels_to_an_issue(github_slug, pull_request.number, [label])
end

#pull_request_body(branch) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
# File 'lib/gitx/github.rb', line 79

def pull_request_body(branch)
  changelog = run_git_cmd('log', "origin/#{config.base_branch}...#{branch}", '--reverse', '--no-merges', '--pretty=format:* %B')
  description = options[:description]

  description_template = []
  description_template << "#{description}\n" if description
  description_template << changelog
  description_template << "#{pull_request_template}\n" if pull_request_template

  ask_editor(description_template.join("\n"), editor: repo.config['core.editor'], footer: PULL_REQUEST_FOOTER)
end

#pull_request_templateObject



99
100
101
# File 'lib/gitx/github.rb', line 99

def pull_request_template
  @pull_request_template ||= File.exist?(pull_request_template_file) ? File.read(pull_request_template_file) : nil
end

#pull_request_template_fileObject



95
96
97
# File 'lib/gitx/github.rb', line 95

def pull_request_template_file
  File.expand_path(PULL_REQEST_TEMPLATE_FILE)
end

#pull_request_title(branch) ⇒ Object



91
92
93
# File 'lib/gitx/github.rb', line 91

def pull_request_title(branch)
  options[:title] || branch.gsub(/[-_]/, ' ')
end

#save_global_config(options) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
# File 'lib/gitx/github.rb', line 162

def save_global_config(options)
  config_dir = File.dirname(global_config_file)
  ::FileUtils.mkdir_p(config_dir, mode: 0o700) unless File.exist?(config_dir)

  @config = global_config.merge(options)
  File.open(global_config_file, 'a+') do |file|
    file.truncate(0)
    file.write(@config.to_yaml)
  end
  File.chmod(0o600, global_config_file)
end

#update_review_status(pull_request, state, description) ⇒ Object

Update build status with peer review status



56
57
58
59
# File 'lib/gitx/github.rb', line 56

def update_review_status(pull_request, state, description)
  commit_sha = pull_request.head.sha
  github_client.create_status(github_slug, commit_sha, state, context: REVIEW_CONTEXT, description: description)
end

#usernameString

Returns github username (ex: ‘wireframe’) of the current github.user.

Returns:

  • (String)

    github username (ex: ‘wireframe’) of the current github.user

Raises:

  • error if github.user is not configured



133
134
135
136
137
138
# File 'lib/gitx/github.rb', line 133

def username
  username = repo.config['github.user']
  raise "Github user not configured.  Run: `git config --global github.user '[email protected]'`" unless username

  username
end