herodot 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 29a451b50c5b14cc6e2f1acf802439ce7755932f
4
- data.tar.gz: 510e67c25f443cfe889fc5f8b754d3c519dd0b42
3
+ metadata.gz: 47210cf5317cca524e9519a983cc37f6d51f9434
4
+ data.tar.gz: a70cf7144148edc5ec91725816af393467c6d24d
5
5
  SHA512:
6
- metadata.gz: c3040f3a6f6f29870e5a7f0ceb4993f644919be1e81774b6822a51d7187dd829510763a159bc9096c28390bc51960c1c2e021cbb3ee46922753cabb1251a9270
7
- data.tar.gz: 76cd7068583335589940f231424fefe727439cea68073e46bf49961a1bb35259e34da07483666fe4a2ca0e5faf82ffe38726f025d31d354942a8eb3ce24087fa
6
+ metadata.gz: d8590a06ba8a42afcbf55dc4911797bcda422d4b71f5d9eb78a7f9f5e813f5f1fe1af1a009311d3e32727d0652571d7011de70593fbc9413fc1d5aa20a60e730
7
+ data.tar.gz: 9750bb7f4d5d46c13c5667e240b177f617a830173f69f54a5f2779299b45a0b8d09ab57c35233c3571e2f0f8c932581d3c9efabc822c457fb0f5e4b13646b53a
data/.herodot.yml ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ :link: https://github.com/bitcrowd/herodot/issues/
3
+ :pattern: "\\d+"
data/README.md CHANGED
@@ -49,6 +49,21 @@ Show Help:
49
49
  $ herodot help track
50
50
  $ herodot help show
51
51
 
52
+ ## Linking to issue trackers
53
+ If you use https://github.com/bitcrowd/tickety-tick or otherwise have branch names, that contain
54
+ the issue number, you can link a tracked herodot repository with your issue tracker, so it
55
+ will print urls of issues it recognizes under the branch name.
56
+
57
+ To use this feature set up a link with
58
+
59
+ $ herodot link
60
+
61
+ You are then guided through the process of linking. When using JIRA or Github with tickety-tick, this should be rather self-explaining, but you can also set up a custom tracker if you are using something different. Just choose `other` and add a URL, to which issue numbers can be appended and a Ruby style regular expression, to cut out the issue number out of your branches.
62
+
63
+ The result will be written into a `.herodot.yml` file in the current or specified directory.
64
+
65
+ HINT: If you do not want to add `.herodot.yml` into your repo or `.gitignore`, you can add it to `./.git/info/exclude` as well.
66
+
52
67
  ## Configuration
53
68
 
54
69
  Herodot writes a configuration yaml to `~/.herodot.yml` with something like this:
@@ -14,7 +14,8 @@ class Herodot::Commands
14
14
  range = Chronic.parse(subject, guess: false, context: :past)
15
15
  abort "Date not parsable: #{args.join(' ')}" unless range
16
16
  worklog = Herodot::Parser.parse(range, config)
17
- output = Herodot::Output.print(worklog.totals, opts)
17
+ decorated_worklog = Herodot::ProjectLink.new(worklog)
18
+ output = Herodot::Output.print(decorated_worklog.totals, opts)
18
19
  puts output
19
20
  end
20
21
 
@@ -29,4 +30,32 @@ class Herodot::Commands
29
30
  FileUtils.touch(config.worklog_file)
30
31
  end
31
32
  end
33
+
34
+ def self.link(path)
35
+ path = '.' if path.nil?
36
+ choose do |menu|
37
+ menu.prompt = 'What tracker do you want to link to?'
38
+ menu.choice(:jira) { link_jira(path) }
39
+ menu.choice(:github) { link_github(path) }
40
+ menu.choices(:other) { link_other(path) }
41
+ menu.default = :other
42
+ end
43
+ end
44
+
45
+ def self.link_jira(path)
46
+ prefix = ask('Jira URL prefix (something for https://something.atlassian.net)?')
47
+ pattern = ask('Ticket prefix (ABCD for tickets like ABCD-123)')
48
+ Herodot::ProjectLink.link(path, "http://#{prefix}.atlassian.net/browse/", "#{pattern}-\\d+")
49
+ end
50
+
51
+ def self.link_github(path)
52
+ handle = ask('Github handle (something/something for https://github.com/something/something)?')
53
+ Herodot::ProjectLink.link(path, "https://github.com/#{handle}/issues/", '\\d+')
54
+ end
55
+
56
+ def self.link_other(path)
57
+ url = ask('URL to issue tracker:')
58
+ pattern = ask('Ticket regex pattern (ruby):')
59
+ Herodot::ProjectLink.link(path, url, pattern)
60
+ end
32
61
  end
@@ -49,10 +49,10 @@ class Herodot::Output
49
49
  end
50
50
 
51
51
  def print_day(times)
52
- times.values.group_by { |log| log[:project] }.flat_map do |_, logs|
53
- logs.map do |log|
54
- [colorize(log[:project]), log[:branch], format_time(log[:time])]
55
- end
52
+ times.sort_by { |log| log[:project] }.flat_map do |log|
53
+ lines = [[colorize(log[:project]), log[:branch], format_time(log[:time])]]
54
+ lines << ['', Rainbow(log[:link]).color(80, 80, 80), ''] if log[:link]
55
+ lines
56
56
  end
57
57
  end
58
58
  end
@@ -0,0 +1,52 @@
1
+ class Herodot::ProjectLink
2
+ PROJECT_CONFIG = '.herodot.yml'.freeze
3
+
4
+ def self.project_config_file(path)
5
+ File.join(File.expand_path(path), PROJECT_CONFIG)
6
+ end
7
+
8
+ def self.link(path, link, pattern)
9
+ puts "Write link into #{project_config_file(path)}"
10
+ File.open(project_config_file(path), 'w') do |f|
11
+ YAML.dump({ link: link, pattern: pattern }, f)
12
+ end
13
+ end
14
+
15
+ def initialize(worklog)
16
+ @worklog = worklog
17
+ @project_configurations = {}
18
+ end
19
+
20
+ def totals
21
+ @worklog.totals.map do |date, logs|
22
+ [date, decorated_logs(logs)]
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def decorated_logs(logs)
29
+ logs.map do |log|
30
+ decorated_log(log)
31
+ end
32
+ end
33
+
34
+ def decorated_log(log)
35
+ link = issue_management_link(log)
36
+ return log if link.nil?
37
+ log.merge(link: link)
38
+ end
39
+
40
+ def issue_management_link(log)
41
+ config = @project_configurations.fetch(log[:path], load_project_configuration(log[:path]))
42
+ return nil unless config.fetch(:link, false)
43
+ ticket = log[:branch].scan(Regexp.new(config.fetch(:pattern, /$^/)))
44
+ [config[:link], ticket.first].join if ticket.any?
45
+ end
46
+
47
+ def load_project_configuration(path)
48
+ file = self.class.project_config_file(path)
49
+ return { link: false } unless File.exist?(file)
50
+ File.open(file) { |f| YAML.load(f) }
51
+ end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module Herodot
2
- VERSION = '0.1.8'.freeze
2
+ VERSION = '0.1.9'.freeze
3
3
  end
@@ -15,7 +15,7 @@ class Herodot::Worklog
15
15
  project = project_path.gsub(@config.projects_directory.to_s, '')
16
16
  id = "#{project}:#{branch}"
17
17
  @raw_logs << { time: time, id: id }
18
- @branches[id] = { branch: branch, project: project }
18
+ @branches[id] = { branch: branch, project: project, path: project_path }
19
19
  end
20
20
 
21
21
  def logs_with_events
@@ -48,7 +48,7 @@ class Herodot::Worklog
48
48
  sums[id] ||= { time: 0, **branch(id) }
49
49
  sums[id][:time] += time[:time]
50
50
  end
51
- [date, time_sums]
51
+ [date, time_sums.values]
52
52
  end
53
53
  end
54
54
 
data/lib/herodot.rb CHANGED
@@ -6,6 +6,7 @@ require_relative 'herodot/worklog'
6
6
  require_relative 'herodot/parser'
7
7
  require_relative 'herodot/commands'
8
8
  require_relative 'herodot/output'
9
+ require_relative 'herodot/project_link'
9
10
 
10
11
  class Herodot::Application
11
12
  include Commander::Methods
@@ -19,6 +20,7 @@ class Herodot::Application
19
20
  config = Herodot::Configuration.new
20
21
  track_command(config)
21
22
  show_command(config)
23
+ link_command(config)
22
24
  default_command :show
23
25
  run!
24
26
  end
@@ -27,7 +29,7 @@ class Herodot::Application
27
29
  ', that will log the current branch into the worklog file.'.freeze
28
30
  def track_command(config)
29
31
  command :track do |c|
30
- c.syntax = 'herodot track <repository path>'
32
+ c.syntax = 'herodot track [<repository path>]'
31
33
  c.summary = 'Start tracking a repository'
32
34
  c.description = TRACK_DESCRIPTION
33
35
  c.example 'Start tracking current repository', 'herodot track'
@@ -53,6 +55,20 @@ class Herodot::Application
53
55
  end
54
56
  end
55
57
 
58
+ LINK_DESCRIPTION = 'This command can link a repository to a project issue tracking tool.'\
59
+ ' The commmands writes the settings in `project_path/.herodot.yml`.'.freeze
60
+ def link_command(_)
61
+ command :link do |c|
62
+ c.syntax = 'herodot link [<repository path>]'
63
+ c.summary = 'Link project with issue tracker'
64
+ c.description = SHOW_DESCRIPTION
65
+ c.example 'Link current repository', 'herodot link'
66
+ c.action do |args, _|
67
+ Herodot::Commands.link(args[0])
68
+ end
69
+ end
70
+ end
71
+
56
72
  def show_command_examples(c)
57
73
  c.example 'Shows this weeks worklogs', 'herodot show'
58
74
  c.example 'Shows last weeks worklogs', 'herodot show last week'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: herodot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - bitcrowd
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-03-07 00:00:00.000000000 Z
11
+ date: 2017-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -160,6 +160,7 @@ extensions: []
160
160
  extra_rdoc_files: []
161
161
  files:
162
162
  - ".gitignore"
163
+ - ".herodot.yml"
163
164
  - ".rspec"
164
165
  - ".rubocop.yml"
165
166
  - ".travis.yml"
@@ -176,6 +177,7 @@ files:
176
177
  - lib/herodot/configuration.rb
177
178
  - lib/herodot/output.rb
178
179
  - lib/herodot/parser.rb
180
+ - lib/herodot/project_link.rb
179
181
  - lib/herodot/version.rb
180
182
  - lib/herodot/worklog.rb
181
183
  - post-checkout