bl 0.6.3 → 0.7.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.
@@ -1,7 +1,6 @@
1
1
  module Bl
2
2
  class Command < Thor
3
3
  include Bl::Requestable
4
- include Bl::Formatting
5
4
  include Bl::Printer
6
5
  class_option :format, type: :string, default: 'table', desc: 'set output format'
7
6
 
@@ -0,0 +1,46 @@
1
+ module Bl
2
+ module Commands
3
+ class Category < Command
4
+ def initialize(*)
5
+ @config = Bl::Config.instance
6
+ @url = "projects/#{@config[:project_key]}/categories"
7
+ super
8
+ end
9
+
10
+ desc 'list', 'list categories'
11
+ def list
12
+ res = request(:get, @url)
13
+ puts 'categories:'
14
+ print_response(res, :category)
15
+ end
16
+
17
+ desc 'add [NAME...]', 'add categories'
18
+ def add(*names)
19
+ names.each do |name|
20
+ res = request(:post, @url, name: name)
21
+ puts 'category added'
22
+ print_response(res, :category)
23
+ end
24
+ end
25
+
26
+ desc 'update [ID...]', 'update categories'
27
+ option :name, type: :string
28
+ def update(*ids)
29
+ ids.each do |id|
30
+ res = request(:patch, "#{@url}/#{id}", delete_class_options(options))
31
+ puts 'category updated'
32
+ print_response(res, :category)
33
+ end
34
+ end
35
+
36
+ desc 'delete [ID...]', 'delete categories'
37
+ def delete(*ids)
38
+ ids.each do |id|
39
+ res = request(:delete, "#{@url}/#{id}")
40
+ puts 'category deleted'
41
+ print_response(res, :category)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,28 @@
1
+ module Bl
2
+ module Commands
3
+ class File < Command
4
+ def initialize(*)
5
+ @config = Bl::Config.instance
6
+ @url = "projects/#{@config[:project_key]}"
7
+ super
8
+ end
9
+
10
+ desc 'list PATH', 'list files on PATH'
11
+ def list(path = '')
12
+ res = request(:get, "#{@url}/files/metadata/#{path}")
13
+ print_response(res, :file)
14
+ end
15
+
16
+ desc 'get [ID...]', 'get files'
17
+ def get(*ids)
18
+ ids.each do |id|
19
+ res = request(:get, "#{@url}/files/#{id}")
20
+ f = ::File.new(res.body.filename, 'w')
21
+ f.write(res.body.content)
22
+ f.close
23
+ puts "file #{id} #{res.body.filename} downloaded."
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ module Bl
2
+ module Commands
3
+ class GitRepo < Command
4
+ def initialize(*)
5
+ @config = Bl::Config.instance
6
+ @url = "projects/#{@config[:project_key]}/git/repositories"
7
+ super
8
+ end
9
+
10
+ desc 'list', 'list git repositories'
11
+ def list
12
+ res = request(:get, @url)
13
+ print_response(res, :gitrepo)
14
+ end
15
+
16
+ desc 'show ID', 'show a git repository'
17
+ def show(id)
18
+ res = request(:get, "#{@url}/#{id}")
19
+ print_response(res, :gitrepo)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ module Bl
2
+ module Commands
3
+ class Group < Command
4
+ def initialize(*)
5
+ @config = Bl::Config.instance
6
+ @url = 'groups'
7
+ super
8
+ end
9
+
10
+ desc 'list', 'list groups'
11
+ options order: :string, offset: :numeric, count: :numeric
12
+ def list
13
+ res = request(:get, @url, options.to_h)
14
+ puts formatter.render(res.body, fields: %i(id name))
15
+ end
16
+
17
+ desc 'show GROUP_ID', 'show group'
18
+ def show(id)
19
+ res = request(:get, "#{@url}/#{id}")
20
+ puts formatter.render(res.body.members, fields: USER_FIELDS)
21
+ end
22
+
23
+ desc 'add GROUP_NAME', 'add group'
24
+ options members: :array
25
+ def add(name)
26
+ res = request(:post, @url, { name: name }.merge(delete_class_options(options)))
27
+ puts 'group added'
28
+ print_group_and_members(res.body)
29
+ end
30
+
31
+ desc 'update GROUP_ID', 'update group'
32
+ options name: :string, members: :array
33
+ def update(id)
34
+ res = request(:patch, "#{@url}/#{id}", delete_class_options(options.to_h))
35
+ puts 'group updated'
36
+ print_group_and_members(res.body)
37
+ end
38
+
39
+ desc 'delete GROUP_ID', 'delete group'
40
+ def delete(id)
41
+ res = request(:delete, "#{@url}/#{id}")
42
+ puts 'group deleted'
43
+ print_group_and_members(res.body)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,104 @@
1
+ module Bl
2
+ module Commands
3
+ class Issue < Command
4
+ def initialize(*)
5
+ @config = Bl::Config.instance
6
+ @url = 'issues'
7
+ super
8
+ end
9
+
10
+ desc 'add [SUBJECT...]', 'add issues'
11
+ options ISSUE_BASE_ATTRIBUTES
12
+ def add(*subjects)
13
+ subjects.each do |s|
14
+ issue_default_options = @config[:issue][:default]
15
+ res = request(:post,
16
+ 'issues',
17
+ issue_default_options.merge({summary: s}).merge(delete_class_options(options.to_h))
18
+ )
19
+ puts '💡 issue added'
20
+ print_response(res, :issue)
21
+ end
22
+ end
23
+
24
+ desc 'close [KEY...]', 'close issues'
25
+ def close(*keys)
26
+ keys.each do |k|
27
+ res = request(:patch, "issues/#{k}", statusId: 4)
28
+ puts '🎉 issue closed'
29
+ print_response(res, :issue)
30
+ end
31
+ end
32
+
33
+ desc 'count', 'count issues'
34
+ options ISSUES_PARAMS
35
+ def count
36
+ puts request(:get, 'issues/count', delete_class_options(options.to_h)).body.count
37
+ end
38
+
39
+ desc 'edit KEY', "edit issues' description by $EDITOR"
40
+ def edit(key)
41
+ issue_description = request(:get, "issues/#{key}").body.description
42
+ file = Tempfile.new
43
+ file.puts(issue_description)
44
+ file.close
45
+ begin
46
+ file.open
47
+ system("$EDITOR #{file.path}")
48
+ new_content = file.read
49
+ request(:patch, "issues/#{key}", description: new_content)
50
+ puts "issue #{key} updated."
51
+ ensure
52
+ file.close
53
+ file.unlink
54
+ end
55
+ end
56
+
57
+ desc 'list', 'list issues by typical ways'
58
+ option :all
59
+ option :unassigned
60
+ option :today
61
+ option :overdue
62
+ option :priority
63
+ option :nocategory
64
+ def list
65
+ opts = {}
66
+ opts[:statusId] = [1, 2, 3] unless options[:all]
67
+ opts[:assigneeId] = [-1] if options[:unassigned]
68
+ if options[:today]
69
+ today = Date.today
70
+ opts[:dueDateSince] = today.to_s
71
+ opts[:dueDateUntil] = today.next.to_s
72
+ end
73
+ opts[:dueDateUntil] = Date.today.to_s if options[:overdue]
74
+ if options[:priority]
75
+ opts[:sort] = 'priority'
76
+ opts[:order] = 'asc'
77
+ end
78
+ opts[:categoryId] = [-1] if options[:nocategory]
79
+ opts[:count] = ISSUES_COUNT_MAX
80
+ res = request(:get, 'issues', opts)
81
+ print_response(res, :issue)
82
+ end
83
+
84
+ desc 'update [KEY...]', 'update issues'
85
+ options ISSUE_BASE_ATTRIBUTES
86
+ option :comment, type: :string
87
+ def update(*keys)
88
+ keys.each do |k|
89
+ res = request(:patch, "issues/#{k}", delete_class_options(options.to_h))
90
+ puts 'issue updated'
91
+ print_response(res, :issue)
92
+ end
93
+ end
94
+
95
+ desc 'search', 'search issues'
96
+ options ISSUES_PARAMS
97
+ def search
98
+ res = request(:get, 'issues', delete_class_options(options.to_h))
99
+ print_response(res, :issue)
100
+ end
101
+
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,60 @@
1
+ module Bl
2
+ module Commands
3
+ class Milestone < Command
4
+ def initialize(*)
5
+ @config = Bl::Config.instance
6
+ @url = "projects/#{@config[:project_key]}/versions"
7
+ super
8
+ end
9
+
10
+ desc 'list', 'list milestones'
11
+ option :all
12
+ def list
13
+ res = request(:get, @url)
14
+ if options[:all]
15
+ else
16
+ res.body.select! { |m| m.archived == false } unless options[:all]
17
+ end
18
+ puts 'milestones:'
19
+ print_response(res, :milestone)
20
+ end
21
+
22
+ desc 'add [NAME...]', 'add milestones'
23
+ options MILESTONE_PARAMS
24
+ def add(*names)
25
+ names.each do |name|
26
+ res = request(
27
+ :post,
28
+ @url,
29
+ name: name,
30
+ description: options[:description],
31
+ startDate: options[:startDate],
32
+ releaseDueDate: options[:releaseDueDate]
33
+ )
34
+ puts 'milestone added'
35
+ print_response(res, :milestone)
36
+ end
37
+ end
38
+
39
+ desc 'update [ID...]', 'update milestones'
40
+ option :name, type: :string
41
+ options MILESTONE_PARAMS
42
+ def update(*ids)
43
+ ids.each do |id|
44
+ res = request(:patch, "#{@url}/#{id}", delete_class_options(options))
45
+ puts 'milestone updated'
46
+ print_response(res, milestone)
47
+ end
48
+ end
49
+
50
+ desc 'delete [ID...]', 'delete milestones'
51
+ def delete(*ids)
52
+ ids.each do |id|
53
+ res = request(:delete, "#{@url}/#{id}")
54
+ puts 'milestone deleted'
55
+ print_response(res, :milestone)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,41 @@
1
+ module Bl
2
+ module Commands
3
+ class Notification < Command
4
+ # TODO:
5
+
6
+ def initialize(*)
7
+ @config = Bl::Config.instance
8
+ @url = 'notifications'
9
+ super
10
+ end
11
+
12
+ desc 'list', ''
13
+ options minId: :numeric, maxId: :numeric, count: :numeric, order: :string
14
+ def list
15
+ res = request(:get, @url, options.to_h)
16
+ res.body.map { |n| puts n.pretty_inspect }
17
+ end
18
+
19
+ desc 'count', ''
20
+ options alreadyRead: :boolean, resourceAlreadyRead: :boolean
21
+ def count
22
+ # puts request(:get, "#{@url}/count").body.count
23
+ # TODO fix nil error
24
+ end
25
+
26
+ desc 'mark-as-read', ''
27
+ def mark_as_read
28
+ res = request(:post, "#{@url}/markAsRead")
29
+ puts 'notifications mark as readed'
30
+ puts res.body.count
31
+ end
32
+
33
+ desc 'read NOTIFICATIONS_ID', ''
34
+ def read(id)
35
+ res = request(:post, "#{@url}/#{id}/markAsRead")
36
+ puts "notifications #{id} readed"
37
+ puts res.pretty_inspect
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,127 @@
1
+ module Bl
2
+ module Commands
3
+ class Project < Command
4
+ def initialize(*)
5
+ @config = Bl::Config.instance
6
+ @url = 'projects'
7
+ super
8
+ end
9
+
10
+ # TODO:
11
+ # desc 'activities ID', 'show project activities'
12
+ # def activities(id)
13
+ # res = request(:get, "#{@url}/#{id}/activities")
14
+ # res.body.each do |a|
15
+ # p a.pretty_inspect
16
+ # end
17
+ # end
18
+
19
+ desc 'list', 'list projects'
20
+ option :all
21
+ def list
22
+ opts = {}
23
+ opts[:archived] = false unless options[:all]
24
+ res = request(:get, @url, opts)
25
+ print_response(res, :project)
26
+ end
27
+
28
+ desc 'show', 'show project'
29
+ def show(id)
30
+ res = request(:get, "#{@url}/#{id}")
31
+ print_response(res, :project)
32
+ rescue => e
33
+ puts e.message
34
+ end
35
+
36
+ desc 'add', 'add project'
37
+ option :key, required: true, type: :string
38
+ option :chartEnabled, type: :boolean, default: false
39
+ option :projectLeaderCanEditProjectLeader, type: :boolean, default: false
40
+ option :subtaskingEnabled, type: :boolean, default: false
41
+ option :textFormattingRule, type: :string, default: 'markdown'
42
+ def add(name)
43
+ res = request(:post, @url, {name: name}.merge(delete_class_options(options.to_h)))
44
+ puts 'project added'
45
+ print_response(res, :project)
46
+ end
47
+
48
+ desc 'update', 'update project'
49
+ options PROJECT_PARAMS
50
+ def update(id)
51
+ res = request(:patch, "#{@url}/#{id}", delete_class_options(options.to_h))
52
+ puts 'project updated'
53
+ print_response(res, :project)
54
+ end
55
+
56
+ desc 'delete', 'delete project'
57
+ def delete(id)
58
+ res = request(:delete, "#{@url}/#{id}")
59
+ puts 'project deleted'
60
+ print_response(res, :project)
61
+ end
62
+
63
+ desc 'status ID', 'show project status'
64
+ def status(id)
65
+ all_issues_count = count_issues(id)
66
+ open_issues_count = count_issues(id, statusId: [1])
67
+ in_progress_issues_count = count_issues(id, statusId: [2])
68
+ resolved_issues_count = count_issues(id, statusId: [3])
69
+ closed_issues_count = count_issues(id, statusId: [4])
70
+ puts "#{closed_issues_count} / #{all_issues_count}"
71
+ puts "open: #{open_issues_count}"
72
+ puts "in progress: #{in_progress_issues_count}"
73
+ puts "resolved: #{resolved_issues_count}"
74
+ puts "closed: #{closed_issues_count}"
75
+ end
76
+
77
+ desc 'progress ID', 'show project progress'
78
+ def progress(id)
79
+ puts '--status--'
80
+ all_issues_count = count_issues(id)
81
+ closed_issues_count = count_issues(id, statusId: [4])
82
+ puts "#{closed_issues_count} / #{all_issues_count}"
83
+ puts '--milestone--'
84
+ versions = request(:get, "projects/#{@config[:project_key]}/versions").body
85
+ versions.each do |version|
86
+ all_issues_count = count_issues(id, milestoneId: [version.id])
87
+ closed_issues_count = count_issues(id, milestoneId: [version.id], statusId: [4])
88
+ puts "#{version.name}: #{closed_issues_count} / #{all_issues_count}"
89
+ end
90
+ puts '--category--'
91
+ categories = request(:get, "projects/#{@config[:project_key]}/categories").body
92
+ categories.each do |category|
93
+ all_issues_count = count_issues(id, categoryId: [category.id])
94
+ closed_issues_count = count_issues(id, categoryId: [category.id], statusId: [4])
95
+ puts "#{category.name}: #{closed_issues_count} / #{all_issues_count}"
96
+ end
97
+ end
98
+
99
+ desc 'users ID', 'show project users'
100
+ def users(id)
101
+ res = request(:get, "#{@url}/#{id}/users")
102
+ puts formatter.render(res.body, fields: USER_FIELDS)
103
+ end
104
+
105
+ desc 'image ID', 'get project image file'
106
+ def image(id)
107
+ res = request(:get, "#{@url}/#{id}/image")
108
+ ::File.open(res.body.filename, 'wb') { |f| f.write(res.body.content) }
109
+ puts "#{res.body.filename} generated"
110
+ end
111
+
112
+ private
113
+
114
+ def count_issues(project_id, args={})
115
+ args = {
116
+ projectId: [project_id],
117
+ }.merge(args)
118
+ request(
119
+ :get,
120
+ 'issues/count',
121
+ args
122
+ ).body.count
123
+ end
124
+
125
+ end
126
+ end
127
+ end