terjira 0.1.1 → 0.2.0

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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -1
  3. data/Gemfile.lock +3 -3
  4. data/README.md +14 -15
  5. data/bin/console +1 -1
  6. data/bin/jira +11 -3
  7. data/bin/terjira +22 -0
  8. data/lib/terjira/base_cli.rb +5 -3
  9. data/lib/terjira/board_cli.rb +17 -2
  10. data/lib/terjira/client/agile.rb +10 -13
  11. data/lib/terjira/client/auth_option_builder.rb +1 -1
  12. data/lib/terjira/client/base.rb +9 -12
  13. data/lib/terjira/client/board.rb +13 -3
  14. data/lib/terjira/client/field.rb +12 -2
  15. data/lib/terjira/client/issue.rb +15 -13
  16. data/lib/terjira/client/issuetype.rb +18 -0
  17. data/lib/terjira/client/jql_builder.rb +25 -0
  18. data/lib/terjira/client/priority.rb +1 -1
  19. data/lib/terjira/client/resolution.rb +1 -1
  20. data/lib/terjira/client/status.rb +1 -1
  21. data/lib/terjira/client/user.rb +5 -6
  22. data/lib/terjira/ext/jira_ruby.rb +12 -4
  23. data/lib/terjira/ext/tty_prompt.rb +0 -3
  24. data/lib/terjira/issue_cli.rb +11 -7
  25. data/lib/terjira/option_support/option_selector.rb +20 -9
  26. data/lib/terjira/option_support/shared_options.rb +4 -2
  27. data/lib/terjira/option_supportable.rb +24 -0
  28. data/lib/terjira/presenters/common_presenter.rb +13 -4
  29. data/lib/terjira/presenters/issue_presenter.rb +115 -97
  30. data/lib/terjira/presenters/project_presenter.rb +1 -1
  31. data/lib/terjira/presenters/sprint_presenter.rb +9 -9
  32. data/lib/terjira/sprint_cli.rb +1 -0
  33. data/lib/terjira/utils/file_cache.rb +26 -26
  34. data/lib/terjira/version.rb +1 -1
  35. data/lib/terjira.rb +11 -0
  36. data/terjira.gemspec +4 -4
  37. metadata +11 -11
  38. data/lib/terjira/client/jql_query_builer.rb +0 -25
@@ -16,7 +16,12 @@ module Terjira
16
16
  def show(issue_key = nil)
17
17
  return invoke(:help) unless issue_key
18
18
  issue = client_class.find(issue_key)
19
- render_issue_detail(issue)
19
+ if issue.issuetype.name.casecmp('epic').zero?
20
+ epic_issues = client_class.all_epic_issues(issue)
21
+ render_issue_detail(issue, epic_issues)
22
+ else
23
+ render_issue_detail(issue)
24
+ end
20
25
  end
21
26
 
22
27
  desc '( ls | list )', 'List of issues'
@@ -56,14 +61,11 @@ module Terjira
56
61
 
57
62
  desc 'new', 'Create issue'
58
63
  jira_options :summary, :description, :project, :issuetype,
59
- :priority, :assignee
64
+ :priority, :assignee, :parent, :epiclink
60
65
  def new
61
66
  opts = suggest_options(required: [:project, :summary, :issuetype])
62
67
 
63
- if opts[:issuetype].key_value.casecmp('epic').zero?
64
- epic_name_field = Client::Field.epic_name
65
- opts[epic_name_field.key] = write_epic_name
66
- end
68
+ suggest_related_value_options(opts)
67
69
 
68
70
  issue = client_class.create(opts)
69
71
  render_issue_detail(issue)
@@ -71,11 +73,13 @@ module Terjira
71
73
 
72
74
  desc 'edit', 'Edit issue'
73
75
  jira_options :summary, :description, :project, :issuetype,
74
- :priority, :assignee
76
+ :priority, :assignee, :epiclink
75
77
  def edit(issue)
76
78
  return if options.blank?
77
79
  issue = client_class.find(issue)
78
80
  opts = suggest_options(resources: { issue: issue })
81
+ suggest_related_value_options(opts)
82
+
79
83
  issue = client_class.update(issue, opts)
80
84
  render_issue_detail(issue)
81
85
  end
@@ -61,7 +61,8 @@ module Terjira
61
61
 
62
62
  def select_issuetype
63
63
  fetch(:issuetype) do
64
- project = select_project
64
+ project = get(:issue).try(:project).try(:key)
65
+ project ||= select_project
65
66
  if project.is_a? String
66
67
  project = Client::Project.find(project)
67
68
  set(:project, project)
@@ -79,14 +80,14 @@ module Terjira
79
80
  fetch(:status) do
80
81
  statuses = fetch(:statuses) do
81
82
  project = if issue = get(:issue)
82
- if issue.respond_to?(:project)
83
- issue.project
84
- else
85
- set(:issue, Client::Issue.find(issue)).project
86
- end
87
- else
88
- select_project
89
- end
83
+ if issue.respond_to?(:project)
84
+ issue.project
85
+ else
86
+ set(:issue, Client::Issue.find(issue)).project
87
+ end
88
+ else
89
+ select_project
90
+ end
90
91
  Client::Status.all(project)
91
92
  end
92
93
 
@@ -120,6 +121,12 @@ module Terjira
120
121
  end
121
122
  end
122
123
 
124
+ def write_epiclink_key
125
+ fetch(:epiclink) do
126
+ option_prompt.ask('Epic key?')
127
+ end
128
+ end
129
+
123
130
  def write_epic_name
124
131
  option_prompt.ask('Epic name?')
125
132
  end
@@ -142,6 +149,10 @@ module Terjira
142
149
  fetch(:summary) { option_prompt.ask('Summary?') }
143
150
  end
144
151
 
152
+ def write_parent_issue_key
153
+ fetch(:parent) { option_prompt.ask('Parent issue key?') }
154
+ end
155
+
145
156
  private
146
157
 
147
158
  def sprint_choice_title(sprint)
@@ -4,7 +4,6 @@ module Terjira
4
4
  'project' => {
5
5
  type: :string,
6
6
  aliases: '-p',
7
- desc: 'project key'
8
7
  },
9
8
  'board' => {
10
9
  type: :numeric,
@@ -31,7 +30,6 @@ module Terjira
31
30
  'status' => {
32
31
  type: :string,
33
32
  aliases: '-s',
34
- desc: 'status'
35
33
  },
36
34
  'resolution' => {
37
35
  type: :string,
@@ -56,6 +54,10 @@ module Terjira
56
54
  'comment' => {
57
55
  type: :string,
58
56
  aliases: '-m'
57
+ },
58
+ 'epiclink' => {
59
+ type: :string,
60
+ aliases: '-e'
59
61
  }
60
62
  }.freeze
61
63
 
@@ -23,6 +23,7 @@ module Terjira
23
23
  status: :select_issue_status,
24
24
  priority: :select_priority,
25
25
  resolution: :select_resolution,
26
+ epiclink: :write_epiclink_key,
26
27
  comment: :write_comment
27
28
  }.freeze
28
29
 
@@ -73,6 +74,29 @@ module Terjira
73
74
  origin.merge! default_value_options
74
75
  end
75
76
 
77
+ def suggest_related_value_options(opts = {})
78
+ if opts[:issuetype]
79
+ if opts[:issuetype].key_value.casecmp('epic').zero?
80
+ # Suggest epic name
81
+ epic_name_field = Client::Field.epic_name
82
+ opts[epic_name_field.key] ||= write_epic_name
83
+ else
84
+ subtask_issuetypes = Client::Issuetype.subtask_issuetypes.map(&:name)
85
+ if subtask_issuetypes.include? opts[:issuetype].key_value
86
+ # Suggest parent issue
87
+ opts[:parent] ||= write_parent_issue_key
88
+ end
89
+ end
90
+ end
91
+
92
+ if opts[:epiclink]
93
+ epiclink_field = Client::Field.epiclink
94
+ opts[epiclink_field.key] ||= opts.delete(:epiclink)
95
+ end
96
+
97
+ opts
98
+ end
99
+
76
100
  def resource_store
77
101
  ResourceStore.instance
78
102
  end
@@ -5,6 +5,10 @@ require 'pastel'
5
5
 
6
6
  module Terjira
7
7
  module CommonPresenter
8
+ extend Forwardable
9
+
10
+ def_delegators :pastel, :bold, :dim
11
+
8
12
  def render(text)
9
13
  if text.is_a? Array
10
14
  puts text.join("\n")
@@ -17,14 +21,18 @@ module Terjira
17
21
  @pastel ||= Pastel.new
18
22
  end
19
23
 
20
- def formatted_date(date_str)
24
+ def dim_none
25
+ dim('None')
26
+ end
27
+
28
+ def formatted_date(date_str, date_format = '%c')
21
29
  return nil if date_str.nil? || date_str.empty?
22
- Time.parse(date_str).strftime('%c')
30
+ Time.parse(date_str).strftime(date_format)
23
31
  end
24
32
 
25
33
  def username_with_email(user)
26
34
  if user.nil?
27
- 'None'
35
+ dim_none
28
36
  else
29
37
  title = "#{user.name}, #{user.displayName}"
30
38
  title += " <#{user.emailAddress}>" if user.respond_to?(:emailAddress)
@@ -40,12 +48,13 @@ module Terjira
40
48
  # when string display length is longger than length argument
41
49
  def insert_new_line(str, length)
42
50
  str.split(/\r\n|\n/).map do |line|
51
+ line.strip!
43
52
  if line.display_width < 1
44
53
  line
45
54
  else
46
55
  display_length = pastel.strip(line).display_width
47
56
  split_length = (line.length * length / display_length).to_i
48
- line.scan(/.{1,#{split_length}}/).join("\n")
57
+ line.scan(/.{1,#{split_length}}/).join("\n") rescue line
49
58
  end
50
59
  end.join("\n")
51
60
  end
@@ -3,9 +3,12 @@
3
3
  require 'tty-prompt'
4
4
  require 'tty-table'
5
5
  require 'pastel'
6
+ require 'erb'
6
7
 
7
8
  module Terjira
8
9
  module IssuePresenter
10
+ COMMENTS_SIZE = 3
11
+
9
12
  def render_issues(issues, opts = {})
10
13
  return render('Empty') if issues.blank?
11
14
 
@@ -34,63 +37,21 @@ module Terjira
34
37
  end
35
38
  end
36
39
 
37
- def render_issue_detail(issue)
38
- header_title = "#{pastel.bold(issue.key)} in #{issue.project.name}"
39
- header = [insert_new_line(header_title, screen_width - 10)]
40
-
41
- rows = []
42
- rows << pastel.underline.bold(issue.summary)
43
- rows << ''
44
- rows << issue_sutats_bar(issue)
45
- rows << ''
46
-
47
- rows << [pastel.bold('Assignee'), username_with_email(issue.assignee)].join(' ')
48
- rows << [pastel.bold('Reporter'), username_with_email(issue.reporter)].join(' ')
49
- rows << ''
50
- rows << pastel.bold('Description')
51
- rows << (issue.description.blank? ? 'None' : issue.description)
52
-
53
- if issue.respond_to?(:environment) && issue.environment.present?
54
- rows << pastel.bold('Environment')
55
- rows << issue.environment
56
- end
57
-
58
- if issue.comments.present?
59
- rows << ''
60
- rows << pastel.bold('Comments')
61
- remain_comments = issue.comments
62
- comments = remain_comments.pop(4)
63
-
64
- if comments.size.zero?
65
- rows << 'None'
66
- elsif remain_comments.empty?
67
- rows << pastel.dim("- #{remain_comments.size} previous comments exist -")
68
- end
69
-
70
- comments.each do |comment|
71
- comment_title = pastel.bold(comment.author['displayName'])
72
- comment_title += " #{formatted_date(comment.created)}"
73
- rows << comment_title
74
- rows << comment.body
75
- rows << ''
76
- end
77
- end
78
-
79
- rows = rows.map { |row| insert_new_line(row, screen_width - 10) }
80
-
81
- table = TTY::Table.new header, rows.map { |r| [r] }
82
- result = table.render(:unicode, padding: [0, 1, 0, 1], multiline: true)
83
-
84
- render(result)
40
+ def render_issue_detail(issue, epic_issues = [])
41
+ result = ERB.new(issue_detail_template, nil, '-').result(binding)
42
+ result += ERB.new(comments_template, nil, '-').result(binding)
43
+ rows = insert_new_line(result, screen_width - 10)
44
+ table = TTY::Table.new nil, rows.split("\n").map { |r| [r] }
45
+ render table.render(:unicode, padding: [0, 1, 0, 1], multiline: true)
85
46
  end
86
47
 
87
48
  def summarise_issue(issue)
88
49
  first_line = [colorize_issue_stastus(issue.status),
89
- issue.summary.tr("\t", ' ')].join
50
+ issue.summary.tr("\t", ' ')].join(' ')
90
51
 
91
52
  second_line = [colorize_priority(issue.priority),
92
53
  colorize_issue_type(issue.issuetype),
93
- assign_info(issue)].join(' ')
54
+ issue.assignee.try(:name)].join(' ')
94
55
 
95
56
  lines = [first_line, second_line].map do |line|
96
57
  insert_new_line(line, screen_width - 30)
@@ -98,67 +59,124 @@ module Terjira
98
59
  lines.join("\n")
99
60
  end
100
61
 
101
- private
102
-
103
- def assign_info(issue)
104
- reporter = issue.reporter ? issue.reporter.name : 'None'
105
- assignee = issue.assignee ? issue.assignee.name : 'None'
106
- "#{reporter} #{assignee}"
62
+ def issue_detail_template
63
+ """<%= bold(issue.key) + ' in ' + issue.project.name %>
64
+
65
+ <%= pastel.underline.bold(issue.summary) %>
66
+
67
+ <%= bold('Type') %>: <%= colorize_issue_type(issue.issuetype) %>\s\s\s<%= bold('Status') %>: <%= colorize_issue_stastus(issue.status) %>\s\s\s<%= bold('priority') %>: <%= colorize_priority(issue.priority, title: true) %>
68
+ <% if issue.parent.nil? -%>
69
+ <%= bold('Epic Link') %>: <%= issue.try(:epic).try(:key) %> <%= issue.try(:epic).try(:name) || dim_none %>
70
+ <% end -%>
71
+ <% if issue.try(:parent) && issue.epic.nil? -%>
72
+ <%= bold('Parent') %>: <%= issue.parent.key %>
73
+ <% end %>
74
+ <% if issue.try(:sprint) -%>
75
+ <%= bold('Sprint') %>: <%= colorize_sprint_state(issue.try(:sprint).try(:state)) %> <%= issue.try(:sprint).try(:id) %>. <%= issue.try(:sprint).try(:name) %>
76
+ <% end -%>
77
+
78
+ <%= bold('Assignee') %>: <%= username_with_email(issue.assignee) %>
79
+ <%= bold('Reporter') %>: <%= username_with_email(issue.reporter) %>
80
+
81
+ <%= bold('Description') %>
82
+ <%= issue.description || dim_none %>
83
+ <% if issue.try(:timetracking).is_a? Hash -%>
84
+
85
+ <%= bold('Estimate') %>
86
+ <% if issue.timetracking['originalEstimate'] -%>
87
+ <%= issue.timetracking['originalEstimate'] %> / <%= issue.timetracking['remainingEstimate'] %>
88
+ <% else -%>
89
+ <%= dim_none %>
90
+ <% end -%>
91
+ <% end -%>
92
+ <% if issue.try(:environment) -%>
93
+
94
+ <%= bold('Environment') %>
95
+ <%= issue.environment %>
96
+ <% end -%>
97
+ <% if issue.subtasks.size > 0 -%>
98
+
99
+ <%= bold('SubTasks') %>
100
+ <% issue.subtasks.each do |subtask| -%>
101
+ * <%= bold(subtask.key) %> <%= colorize_issue_stastus(subtask.status) %> <%= subtask.summary %>
102
+ <% end -%>
103
+ <% end -%>
104
+ <% if epic_issues.present? -%>
105
+ <%= bold('Issues in Epic') %>
106
+ <% epic_issues.each do |epic_issue| -%>
107
+ * <%= bold(epic_issue.key) %> <%= colorize_issue_stastus(epic_issue.status) %> <%= epic_issue.summary %> <%= issue.assignee.try(:name) %>
108
+ <% end -%>
109
+ <% end -%>
110
+ """
107
111
  end
108
112
 
109
- def issue_sutats_bar(issue)
110
- bar = ["#{pastel.bold('Type')}: #{colorize_issue_type(issue.issuetype)}",
111
- "#{pastel.bold('Status')}: #{colorize_issue_stastus(issue.status)}",
112
- "#{pastel.bold('priority')}: #{colorize_priority(issue.priority, title: true)}"]
113
- bar.join("\s\s\s")
113
+ def comments_template
114
+ """
115
+ <% remain_comments = issue.comments -%>
116
+ <% visiable_comments = remain_comments.pop(COMMENTS_SIZE) -%>
117
+ <%= bold('Comments') %>
118
+ <% if visiable_comments.empty? -%>
119
+ <%= dim_none %>
120
+ <% elsif remain_comments.size != 0 -%>
121
+ <%= pastel.dim('- ' + remain_comments.size.to_s + ' previous comments exist -') %>
122
+ <% end -%>
123
+ <% visiable_comments.each do |comment| -%>
124
+ <%= pastel.bold(comment.author['displayName']) %> <%= formatted_date(comment.created) %>
125
+ <%= comment.body %>
126
+
127
+ <% end -%>
128
+ """
114
129
  end
115
130
 
131
+ private
132
+
116
133
  def colorize_issue_type(issue_type)
117
134
  title = " #{issue_type.name} "
118
- if title =~ /bug/i
119
- pastel.on_red.white.bold(title)
120
- elsif title =~ /task/i
121
- pastel.on_blue.white.bold(title)
122
- elsif title =~ /story/i
123
- pastel.on_green.white.bold(title)
124
- elsif title =~ /epic/i
125
- pastel.on_magenta.white.bold(title)
126
- else
127
- pastel.on_cyan.white.bold(title)
128
- end
135
+ background = if title =~ /bug/i
136
+ :on_red
137
+ elsif title =~ /task/i
138
+ :on_blue
139
+ elsif title =~ /story/i
140
+ :on_green
141
+ elsif title =~ /epic/i
142
+ :on_magenta
143
+ else
144
+ :on_cyan
145
+ end
146
+ pastel.decorate(title, :white, background, :bold)
129
147
  end
130
148
 
131
149
  def colorize_issue_stastus(status)
132
- title = "#{status.name} "
133
- category = title
134
- if status.respond_to? :statusCategory
135
- category = (status.statusCategory || {})['name'] || ''
136
- end
137
- if category =~ /to\sdo|open/i
138
- pastel.blue.bold(title)
139
- elsif category =~ /in\sprogress/i
140
- pastel.yellow.bold(title)
141
- elsif category =~ /done|close/i
142
- pastel.green.bold(title)
143
- else
144
- pastel.magenta.bold(title)
145
- end
150
+ category = status.statusCategory['name'] rescue nil
151
+ category ||= status.name
152
+ title = "#{status.name}"
153
+
154
+ color = if category =~ /to\sdo|open/i
155
+ :blue
156
+ elsif category =~ /in\sprogress/i
157
+ :yellow
158
+ elsif category =~ /done|close/i
159
+ :green
160
+ else
161
+ :magenta
162
+ end
163
+ pastel.decorate(title, color, :bold)
146
164
  end
147
165
 
148
166
  def colorize_priority(priority, opts = {})
149
167
  return '' unless priority.respond_to? :name
150
168
  name = priority.name
151
- info = if name =~ /high|major|critic/i
152
- { color: :red, icon: '⬆' }
153
- elsif name =~ /medium|default/i
154
- { color: :yellow, icon: '⬆' }
155
- elsif name =~ /minor|low|trivial/i
156
- { color: :green, icon: '⬇' }
157
- else
158
- { color: :green, icon: '•' }
159
- end
160
- title = opts[:title] ? "#{info[:icon]} #{name}" : info[:icon]
161
- pastel.send(info[:color], title)
169
+ infos = if name =~ /high|major|critic/i
170
+ [:red, '⬆']
171
+ elsif name =~ /medium|default/i
172
+ [:yellow, '⬆']
173
+ elsif name =~ /minor|low|trivial/i
174
+ [:green, '⬇']
175
+ else
176
+ [:green, '•']
177
+ end
178
+ title = opts[:title] ? "#{infos[1]} #{name}" : infos[1]
179
+ pastel.decorate(title, infos[0])
162
180
  end
163
181
 
164
182
  def extract_status_names(issues)
@@ -12,7 +12,7 @@ module Terjira
12
12
  end
13
13
 
14
14
  rows = projects.map do |project|
15
- [project.key, project.name, project.projectTypeKey]
15
+ [project.key, project.name, project.try(:projectTypeKey)]
16
16
  end
17
17
 
18
18
  table = TTY::Table.new head, rows
@@ -3,19 +3,19 @@
3
3
  module Terjira
4
4
  module SprintPresenter
5
5
  def render_sprint_detail(sprint)
6
- return render("Empty") if sprint.nil?
6
+ return render('Empty') if sprint.nil?
7
7
  attrs = sprint.attrs
8
8
  summary = [
9
9
  pastel.bold("#{sprint.id}. #{sprint.name} #{colorize_sprint_state(sprint.state)}"),
10
- "#{attrs["goal"]}",
11
- "#{formatted_date(attrs["startDate"])} ~ #{formatted_date(attrs["endDate"])}"
10
+ attrs['goal'].to_s,
11
+ "#{formatted_date(attrs['startDate'])} ~ #{formatted_date(attrs['endDate'])}"
12
12
  ]
13
13
 
14
14
  render(summary.reject(&:empty?).join("\n"))
15
15
  end
16
16
 
17
17
  def render_sprints_summary(sprints)
18
- headers = ["ID", "Summary"].map { |h| pastel.bold(h) }
18
+ headers = %w(ID Summary).map { |h| pastel.bold(h) }
19
19
  rows = []
20
20
  sort_sprint_by_state(sprints).each do |sprint|
21
21
  rows << [pastel.bold(sprint.id), summarise_sprint(sprint)]
@@ -30,10 +30,10 @@ module Terjira
30
30
 
31
31
  def summarise_sprint(sprint)
32
32
  summary = colorize_sprint_state(sprint.state)
33
- summary += " " + pastel.bold(sprint.name)
33
+ summary += ' ' + pastel.bold(sprint.name)
34
34
  if sprint.respond_to? :startDate
35
35
  summary += "\n"
36
- summary += formatted_date(sprint.startDate) + " ~ "
36
+ summary += formatted_date(sprint.startDate) + ' ~ '
37
37
  summary += formatted_date(sprint.endDate) if sprint.respond_to? :endDate
38
38
  end
39
39
  summary += "\n#{sprint.goal}" if sprint.respond_to? :goal
@@ -41,10 +41,10 @@ module Terjira
41
41
  end
42
42
 
43
43
  def colorize_sprint_state(state)
44
- state = state.capitalize
45
- if(state =~ /active/i)
44
+ state = state.to_s.capitalize
45
+ if state =~ /active/i
46
46
  pastel.on_blue.bold(state)
47
- elsif(state =~ /close/i)
47
+ elsif state =~ /close/i
48
48
  pastel.dim(state)
49
49
  else
50
50
  pastel.on_magenta.bold(state)
@@ -27,6 +27,7 @@ module Terjira
27
27
  def active
28
28
  opts = suggest_options(required: [:board])
29
29
  board = opts[:board]
30
+
30
31
  sprints = client_class.find_active(board)
31
32
 
32
33
  opts[:assignee] ||= current_username
@@ -3,21 +3,28 @@ require 'fileutils'
3
3
 
4
4
  module Terjira
5
5
  class FileCache
6
-
7
6
  MAX_DEPTH = 32
8
- ROOT_DIR = ENV["HOME"] ? "#{ENV["HOME"]}/.terjira/" : "~/.terjira/"
7
+ ROOT_DIR = ENV['HOME'] ? "#{ENV['HOME']}/.terjira/" : '~/.terjira/'
8
+
9
+ class << self
10
+ def clear_all
11
+ return unless File.exist?(ROOT_DIR)
12
+ FileUtils.rm_r(ROOT_DIR)
13
+ FileUtils.mkdir_p(ROOT_DIR)
14
+ end
15
+ end
9
16
 
10
17
  def initialize(domain, expiry = 0, depth = 2)
11
18
  @domain = domain
12
19
  @expiry = expiry
13
20
  @depth = depth > MAX_DEPTH ? MAX_DEPTH : depth
14
- FileUtils.mkdir_p(get_root)
21
+ FileUtils.mkdir_p(root_path)
15
22
  end
16
23
 
17
24
  # Set a cache value for the given key. If the cache contains an existing value for
18
25
  # the key it will be overwritten.
19
26
  def set(key, value)
20
- f = File.open(get_path(key), "w")
27
+ f = File.open(get_path(key), 'w')
21
28
  Marshal.dump(value, f)
22
29
  f.close
23
30
  end
@@ -31,14 +38,12 @@ module Terjira
31
38
  FileUtils.rm(path)
32
39
  end
33
40
 
34
- if File.exist?(path)
35
- f = File.open(path, "r")
41
+ return nil unless File.exist?(path)
42
+ result = nil
43
+ File.open(path, 'r') do |f|
36
44
  result = Marshal.load(f)
37
- f.close
38
- return result
39
- else
40
- return nil
41
45
  end
46
+ result
42
47
  end
43
48
 
44
49
  # Return the value for the specified key from the cache if the key exists in the
@@ -54,21 +59,20 @@ module Terjira
54
59
 
55
60
  # Delete the value for the given key from the cache
56
61
  def delete(key)
57
- FileUtils.rm(get_path(key))
62
+ FileUtils.rm(get_path(key)) if File.exists? get_path(key)
58
63
  end
59
64
 
60
65
  # Delete ALL data from the cache, regardless of expiry time
61
66
  def clear
62
- if File.exist?(get_root)
63
- FileUtils.rm_r(get_root)
64
- FileUtils.mkdir_p(get_root)
65
- end
67
+ return unless File.exist?(root_path)
68
+ FileUtils.rm_r(root_path)
69
+ FileUtils.mkdir_p(root_path)
66
70
  end
67
71
 
68
72
  # Delete all expired data from the cache
69
73
  def purge
70
74
  @t_purge = Time.new
71
- purge_dir(get_root) if @expiry > 0
75
+ purge_dir(root_path) if @expiry > 0
72
76
  end
73
77
 
74
78
  private
@@ -76,16 +80,14 @@ module Terjira
76
80
  def get_path(key)
77
81
  md5 = Digest::MD5.hexdigest(key.to_s).to_s
78
82
 
79
- dir = File.join(get_root, md5.split(//)[0..@depth - 1])
83
+ dir = File.join(root_path, md5.split(//)[0..@depth - 1])
80
84
  FileUtils.mkdir_p(dir)
81
- return File.join(dir, md5)
85
+ File.join(dir, md5)
82
86
  end
83
87
 
84
- def get_root
85
- if @root == nil
86
- @root = File.join(ROOT_DIR, @domain)
87
- end
88
- return @root
88
+ def root_path
89
+ @root = File.join(ROOT_DIR, @domain) if @root.nil?
90
+ @root
89
91
  end
90
92
 
91
93
  def purge_dir(dir)
@@ -102,9 +104,7 @@ module Terjira
102
104
  end
103
105
 
104
106
  # Delete empty directories
105
- if Dir.entries(dir).delete_if{|e| e =~ /^\.\.?$/}.empty?
106
- Dir.delete(dir)
107
- end
107
+ Dir.delete(dir) if Dir.entries(dir).delete_if { |e| e =~ /^\.\.?$/ }.empty?
108
108
  end
109
109
  end
110
110
  end
@@ -1,3 +1,3 @@
1
1
  module Terjira
2
- VERSION = '0.1.1'.freeze
2
+ VERSION = '0.2.0'.freeze
3
3
  end
data/lib/terjira.rb CHANGED
@@ -13,8 +13,19 @@ module Terjira
13
13
  class CLI < Thor
14
14
  desc 'login', 'login your Jira'
15
15
  def login
16
+ pastel = Pastel.new
16
17
  Client::Base.expire_auth_options
17
18
  Client::Base.build_auth_options
19
+
20
+ # for touch base resource
21
+ Client::Field.all
22
+ puts pastel.blue("Login successful")
23
+ rescue JIRA::HTTPError => e
24
+ puts pastel.red(e.message)
25
+ Client::Base.expire_auth_options
26
+ rescue => e
27
+ Client::Base.expire_auth_options
28
+ raise e
18
29
  end
19
30
 
20
31
  desc 'logout', 'logout your Jira'