bl 0.6.3 → 0.7.0

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