terjira 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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'