mirror of https://github.com/ohmyzsh/ohmyzsh.git
Merge 692ae9a5dc
into 6e9cda3d30
This commit is contained in:
commit
b5dd7e4542
|
@ -0,0 +1,43 @@
|
||||||
|
# JIRA auto-worklog
|
||||||
|
|
||||||
|
This plugin automatically logs time to Atlassian's [JIRA](https://www.atlassian.com/software/jira) bug tracking software when on a git branch with a JIRA issue ID in the branch name.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Add the plugin to the list of plugins for Oh My Zsh to load (inside `~/.zshrc`):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
plugins=(
|
||||||
|
# other plugins...
|
||||||
|
jira-auto-worklog
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Every time the command prompt is generated, the time spent on a JIRA branch is accumulated. Once the accumulated time exceeds a threshold, the time is logged in the background. By default, the time is logged every minute.
|
||||||
|
|
||||||
|
To prevent AFK time from being counted, no time is logged if there is no activity on a JIRA branch for a certain amount of time. By default the AFK threshold is 30m.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
The URL for your JIRA instance is located in the following places, in order of precedence:
|
||||||
|
|
||||||
|
1. `$JIRA_URL` environment variable
|
||||||
|
2. `./.jira-url` file in the current directory
|
||||||
|
3. `~/.jira-url` file in your home directory
|
||||||
|
|
||||||
|
The PAT for your JIRA instance is located in the following places, in order of precedence:
|
||||||
|
|
||||||
|
1. `./.jira-pat` file in the current directory
|
||||||
|
2. `~/.jira-pat` file in your home directory
|
||||||
|
|
||||||
|
Run `jira-auto-worklog-check` in this directory to check if the plugin is correctly configured.
|
||||||
|
|
||||||
|
### Variables
|
||||||
|
|
||||||
|
* `$JIRA_URL` - Your JIRA instance's URL
|
||||||
|
* `$JIRA_AUTO_WORKLOG_AFK_THRESHOLD` - The number of minutes of AFK time before no time is logged. Defaults to 30
|
||||||
|
* `$JIRA_AUTO_WORKLOG_COMMENT` - The comment to add to the work log. Defaults to an empty string
|
||||||
|
* `$JIRA_AUTO_WORKLOG_PRECISION` - The size of the chunks of time that are logged. Must be greater than zero. Defaults to 1. For example, `JIRA_AUTO_WORKLOG_PRECISION=15` will log 15 minutes after being active for 15 minutes a JIRA branch.
|
|
@ -0,0 +1,108 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'net/http'
|
||||||
|
require 'json'
|
||||||
|
require 'yaml'
|
||||||
|
require 'date'
|
||||||
|
|
||||||
|
JIRA_REGEX = /([A-Z]+-\d+)/.freeze
|
||||||
|
CONFIG_PATH = "#{Dir.home}/.jira-auto-worklog"
|
||||||
|
|
||||||
|
def jira_url
|
||||||
|
ENV.fetch('JIRA_URL', nil) ||
|
||||||
|
(File.read('./.jira-url').chomp if File.exist?('./.jira-url')) ||
|
||||||
|
(File.read("#{Dir.home}/.jira-url").chomp if File.exist?("#{Dir.home}/.jira-url")) ||
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def jira_pat
|
||||||
|
(File.read('./.jira-pat').chomp if File.exist?('./.jira-pat')) ||
|
||||||
|
(File.read("#{Dir.home}/.jira-pat").chomp if File.exist?("#{Dir.home}/.jira-pat")) ||
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def afk_threshold
|
||||||
|
ENV.fetch('JIRA_AUTO_WORKLOG_AFK_THRESHOLD', 30).to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def comment
|
||||||
|
ENV.fetch('JIRA_AUTO_WORKLOG_COMMENT', '')
|
||||||
|
end
|
||||||
|
|
||||||
|
def precision
|
||||||
|
ENV.fetch('JIRA_AUTO_WORKLOG_PRECISION', 1).to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
unless jira_url
|
||||||
|
puts 'JIRA URL not found.'
|
||||||
|
puts
|
||||||
|
puts 'Valid Locations are, in order of precedence:'
|
||||||
|
puts ' 1. JIRA_URL environment variable'
|
||||||
|
puts ' 2. ./.jira-url'
|
||||||
|
puts ' 3. ~/.jira-url'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless jira_pat
|
||||||
|
puts 'JIRA Personal Access Token not found.'
|
||||||
|
puts
|
||||||
|
puts 'Valid Locations are, in order of precedence:'
|
||||||
|
puts ' 1. ./.jira-pat'
|
||||||
|
puts ' 2. ~/.jira-pat'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless precision > 0
|
||||||
|
puts 'Precision must be a positive integer.'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
branch = `command git rev-parse --abbrev-ref --symbolic-full-name HEAD 2> /dev/null`
|
||||||
|
exit(0) unless (match = branch.match(JIRA_REGEX))
|
||||||
|
|
||||||
|
ticket = match[1]
|
||||||
|
|
||||||
|
# load the config
|
||||||
|
data = {}
|
||||||
|
if File.exist?(CONFIG_PATH)
|
||||||
|
data = YAML.safe_load(File.read(CONFIG_PATH), permitted_classes: [Time])
|
||||||
|
end
|
||||||
|
data['overflow'] ||= 0
|
||||||
|
data['last_updated'] ||= Time.now
|
||||||
|
|
||||||
|
# Calculate the delta
|
||||||
|
delta_s = Time.now.utc.to_i - data['last_updated'].to_i
|
||||||
|
data['last_updated'] = Time.now.utc
|
||||||
|
|
||||||
|
if (delta_s / 60) > afk_threshold
|
||||||
|
File.write(CONFIG_PATH, YAML.dump(data))
|
||||||
|
exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
time_spent = delta_s + data['overflow']
|
||||||
|
precision_s = precision * 60
|
||||||
|
minutes = (time_spent / precision_s)
|
||||||
|
data['overflow'] = (time_spent % precision_s)
|
||||||
|
File.write(CONFIG_PATH, YAML.dump(data))
|
||||||
|
|
||||||
|
exit(0) if minutes.zero?
|
||||||
|
|
||||||
|
uri = URI("#{jira_url}/rest/api/2/issue/#{ticket}/worklog")
|
||||||
|
|
||||||
|
request = Net::HTTP::Post.new(uri)
|
||||||
|
request['Authorization'] = format('Bearer %s', jira_pat)
|
||||||
|
request['Content-Type'] = 'application/json'
|
||||||
|
request.body = JSON.generate({
|
||||||
|
'timeSpent' => minutes,
|
||||||
|
'comment' => comment
|
||||||
|
})
|
||||||
|
|
||||||
|
Net::HTTP.start(uri.host, uri.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER) do |http|
|
||||||
|
res = http.request(request)
|
||||||
|
if res.is_a?(Net::HTTPSuccess)
|
||||||
|
puts "Logged #{minutes} minutes to #{ticket}"
|
||||||
|
else
|
||||||
|
puts "Failed to log time to #{ticket}"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,65 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'net/http'
|
||||||
|
require 'json'
|
||||||
|
require 'yaml'
|
||||||
|
require 'date'
|
||||||
|
|
||||||
|
JIRA_REGEX = /([A-Z]+-\d+)/.freeze
|
||||||
|
|
||||||
|
def jira_url
|
||||||
|
ENV.fetch('JIRA_URL', nil) ||
|
||||||
|
(File.read('./.jira-url').chomp if File.exist?('./.jira-url')) ||
|
||||||
|
(File.read("#{Dir.home}/.jira-url").chomp if File.exist?("#{Dir.home}/.jira-url")) ||
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def jira_pat
|
||||||
|
(File.read('./.jira-pat').chomp if File.exist?('./.jira-pat')) ||
|
||||||
|
(File.read("#{Dir.home}/.jira-pat").chomp if File.exist?("#{Dir.home}/.jira-pat")) ||
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def precision
|
||||||
|
ENV.fetch('JIRA_AUTO_WORKLOG_PRECISION', 1).to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
unless jira_url
|
||||||
|
puts 'JIRA URL not found.'
|
||||||
|
puts
|
||||||
|
puts 'Valid Locations are, in order of precedence:'
|
||||||
|
puts ' 1. JIRA_URL environment variable'
|
||||||
|
puts ' 2. ./.jira-url'
|
||||||
|
puts ' 3. ~/.jira-url'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless jira_pat
|
||||||
|
puts 'JIRA Personal Access Token not found.'
|
||||||
|
puts
|
||||||
|
puts 'Valid Locations are, in order of precedence:'
|
||||||
|
puts ' 1. ./.jira-pat'
|
||||||
|
puts ' 2. ~/.jira-pat'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless precision > 0
|
||||||
|
puts 'Precision must be a positive integer.'
|
||||||
|
exit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
uri = URI("#{jira_url}/rest/api/2/myself")
|
||||||
|
|
||||||
|
request = Net::HTTP::Get.new(uri)
|
||||||
|
request['Authorization'] = format('Bearer %s', jira_pat)
|
||||||
|
request['Content-Type'] = 'application/json'
|
||||||
|
|
||||||
|
Net::HTTP.start(uri.host, uri.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER) do |http|
|
||||||
|
res = http.request(request)
|
||||||
|
if res.is_a?(Net::HTTPSuccess)
|
||||||
|
puts "Jira auto-worklog is configured correctly. Time will be logged."
|
||||||
|
else
|
||||||
|
puts "Jira auto-worklog is not configured correctly. Please check your JIRA URL and Personal Access Token."
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,20 @@
|
||||||
|
# zle-line-init widget (don't redefine if already defined)
|
||||||
|
(( ! ${+functions[_jira-auto-worklog_zle-line-init]} )) || return 0
|
||||||
|
|
||||||
|
# Get the directory of this file
|
||||||
|
dir="$(dirname "$0")"
|
||||||
|
|
||||||
|
case "$widgets[zle-line-init]" in
|
||||||
|
# Simply define the function if zle-line-init doesn't yet exist
|
||||||
|
builtin|"") function _jira-auto-worklog_zle-line-init() {
|
||||||
|
($dir/jira-auto-worklog &> /dev/null)
|
||||||
|
} ;;
|
||||||
|
# Override the current zle-line-init widget, calling the old one
|
||||||
|
user:*) zle -N _jira-auto-worklog_orig_zle-line-init "${widgets[zle-line-init]#user:}"
|
||||||
|
function _jira-auto-worklog_zle-line-init() {
|
||||||
|
($dir/jira-auto-worklog &> /dev/null)
|
||||||
|
zle _jira-auto-worklog_orig_zle-line-init -- "$@"
|
||||||
|
} ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
zle -N zle-line-init _jira-auto-worklog_zle-line-init
|
Loading…
Reference in New Issue