rujira 0.1.10 → 0.1.14

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
  SHA256:
3
- metadata.gz: 16380f7114ef3fc97d349938fe5fd2d6c064af8bbd5b9b9e475379a005304103
4
- data.tar.gz: 53bf9e9ab04f2cd8f5995536ddf6815272b67975ee648c0dc6c597a58b3f2b97
3
+ metadata.gz: 77641c9b95c2b8777a5e95202deb2bf38ab8d41e1d2e339f95ab5f2c1243bce8
4
+ data.tar.gz: 759fb9ee8e937322f10c266fb88ea71abe7f8f59a66396e18092ef378bcc37af
5
5
  SHA512:
6
- metadata.gz: c7cdc882bace5f02fd760a9c417159d4d99359e102c058e083a4718712e93e797e28d63915630fd86dde3b178a449841e5dcef4b63db51aa30dfac614d7d5e97
7
- data.tar.gz: 9efae9d3c99fa0f12eb29b9224a0226a56cb79a2b32b36f05e0950111d061858876836c51153bcff3e91632500522eedfdc99bdbbaeb2fddea5bbd32c5c6a25d
6
+ metadata.gz: 901f27c13e274d717e52dda2218b9bf70c3432a7a2077f0e70f3203673c4218280e875efb96d50220e4d7e2e07ac81cf2fee2645f3210cc0ed54a911d935fe99
7
+ data.tar.gz: 9cee06af219613b52e24337ad2441a2f10b880e351d2d60075a2aef5b14fd2460813541086047c94db6381588764b6cd7a6a10676c35d48000d85bd9443ea163
data/.rubocop.yml ADDED
@@ -0,0 +1,214 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ Gemspec/AddRuntimeDependency: # new in 1.65
4
+ Enabled: true
5
+ Gemspec/DeprecatedAttributeAssignment: # new in 1.30
6
+ Enabled: true
7
+ Gemspec/DevelopmentDependencies: # new in 1.44
8
+ Enabled: true
9
+ Gemspec/RequireMFA: # new in 1.23
10
+ Enabled: true
11
+ Layout/LineContinuationLeadingSpace: # new in 1.31
12
+ Enabled: true
13
+ Layout/LineContinuationSpacing: # new in 1.31
14
+ Enabled: true
15
+ Layout/LineEndStringConcatenationIndentation: # new in 1.18
16
+ Enabled: true
17
+ Layout/SpaceBeforeBrackets: # new in 1.7
18
+ Enabled: true
19
+ Lint/AmbiguousAssignment: # new in 1.7
20
+ Enabled: true
21
+ Lint/AmbiguousOperatorPrecedence: # new in 1.21
22
+ Enabled: true
23
+ Lint/AmbiguousRange: # new in 1.19
24
+ Enabled: true
25
+ Lint/ArrayLiteralInRegexp: # new in 1.71
26
+ Enabled: true
27
+ Lint/ConstantOverwrittenInRescue: # new in 1.31
28
+ Enabled: true
29
+ Lint/ConstantReassignment: # new in 1.70
30
+ Enabled: true
31
+ Lint/CopDirectiveSyntax: # new in 1.72
32
+ Enabled: true
33
+ Lint/DeprecatedConstants: # new in 1.8
34
+ Enabled: true
35
+ Lint/DuplicateBranch: # new in 1.3
36
+ Enabled: true
37
+ Lint/DuplicateMagicComment: # new in 1.37
38
+ Enabled: true
39
+ Lint/DuplicateMatchPattern: # new in 1.50
40
+ Enabled: true
41
+ Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
42
+ Enabled: true
43
+ Lint/DuplicateSetElement: # new in 1.67
44
+ Enabled: true
45
+ Lint/EmptyBlock: # new in 1.1
46
+ Enabled: true
47
+ Lint/EmptyClass: # new in 1.3
48
+ Enabled: true
49
+ Lint/EmptyInPattern: # new in 1.16
50
+ Enabled: true
51
+ Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
52
+ Enabled: true
53
+ Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
54
+ Enabled: true
55
+ Lint/ItWithoutArgumentsInBlock: # new in 1.59
56
+ Enabled: true
57
+ Lint/LambdaWithoutLiteralBlock: # new in 1.8
58
+ Enabled: true
59
+ Lint/LiteralAssignmentInCondition: # new in 1.58
60
+ Enabled: true
61
+ Lint/MixedCaseRange: # new in 1.53
62
+ Enabled: true
63
+ Lint/NoReturnInBeginEndBlocks: # new in 1.2
64
+ Enabled: true
65
+ Lint/NonAtomicFileOperation: # new in 1.31
66
+ Enabled: true
67
+ Lint/NumberedParameterAssignment: # new in 1.9
68
+ Enabled: true
69
+ Lint/NumericOperationWithConstantResult: # new in 1.69
70
+ Enabled: true
71
+ Lint/OrAssignmentToConstant: # new in 1.9
72
+ Enabled: true
73
+ Lint/RedundantDirGlobSort: # new in 1.8
74
+ Enabled: true
75
+ Lint/RedundantRegexpQuantifiers: # new in 1.53
76
+ Enabled: true
77
+ Lint/RedundantTypeConversion: # new in 1.72
78
+ Enabled: true
79
+ Lint/RefinementImportMethods: # new in 1.27
80
+ Enabled: true
81
+ Lint/RequireRangeParentheses: # new in 1.32
82
+ Enabled: true
83
+ Lint/RequireRelativeSelfPath: # new in 1.22
84
+ Enabled: true
85
+ Lint/SharedMutableDefault: # new in 1.70
86
+ Enabled: true
87
+ Lint/SuppressedExceptionInNumberConversion: # new in 1.72
88
+ Enabled: true
89
+ Lint/SymbolConversion: # new in 1.9
90
+ Enabled: true
91
+ Lint/ToEnumArguments: # new in 1.1
92
+ Enabled: true
93
+ Lint/TripleQuotes: # new in 1.9
94
+ Enabled: true
95
+ Lint/UnescapedBracketInRegexp: # new in 1.68
96
+ Enabled: true
97
+ Lint/UnexpectedBlockArity: # new in 1.5
98
+ Enabled: true
99
+ Lint/UnmodifiedReduceAccumulator: # new in 1.1
100
+ Enabled: true
101
+ Lint/UselessConstantScoping: # new in 1.72
102
+ Enabled: true
103
+ Lint/UselessDefined: # new in 1.69
104
+ Enabled: true
105
+ Lint/UselessNumericOperation: # new in 1.66
106
+ Enabled: true
107
+ Lint/UselessRescue: # new in 1.43
108
+ Enabled: true
109
+ Lint/UselessRuby2Keywords: # new in 1.23
110
+ Enabled: true
111
+ Metrics/CollectionLiteralLength: # new in 1.47
112
+ Enabled: true
113
+ Naming/BlockForwarding: # new in 1.24
114
+ Enabled: true
115
+ Security/CompoundHash: # new in 1.28
116
+ Enabled: true
117
+ Security/IoMethods: # new in 1.22
118
+ Enabled: true
119
+ Style/AmbiguousEndlessMethodDefinition: # new in 1.68
120
+ Enabled: true
121
+ Style/ArgumentsForwarding: # new in 1.1
122
+ Enabled: true
123
+ Style/ArrayIntersect: # new in 1.40
124
+ Enabled: true
125
+ Style/BitwisePredicate: # new in 1.68
126
+ Enabled: true
127
+ Style/CollectionCompact: # new in 1.2
128
+ Enabled: true
129
+ Style/CombinableDefined: # new in 1.68
130
+ Enabled: true
131
+ Style/ComparableBetween: # new in 1.74
132
+ Enabled: true
133
+ Style/ComparableClamp: # new in 1.44
134
+ Enabled: true
135
+ Style/ConcatArrayLiterals: # new in 1.41
136
+ Enabled: true
137
+ Style/DataInheritance: # new in 1.49
138
+ Enabled: true
139
+ Style/DigChain: # new in 1.69
140
+ Enabled: true
141
+ Style/DirEmpty: # new in 1.48
142
+ Enabled: true
143
+ Style/DocumentDynamicEvalDefinition: # new in 1.1
144
+ Enabled: true
145
+ Style/EmptyHeredoc: # new in 1.32
146
+ Enabled: true
147
+ Style/EndlessMethod: # new in 1.8
148
+ Enabled: true
149
+ Style/EnvHome: # new in 1.29
150
+ Enabled: true
151
+ Style/ExactRegexpMatch: # new in 1.51
152
+ Enabled: true
153
+ Style/FetchEnvVar: # new in 1.28
154
+ Enabled: true
155
+ Style/FileEmpty: # new in 1.48
156
+ Enabled: true
157
+ Style/FileNull: # new in 1.69
158
+ Enabled: true
159
+ Style/FileRead: # new in 1.24
160
+ Enabled: true
161
+ Style/FileTouch: # new in 1.69
162
+ Enabled: true
163
+ Style/FileWrite: # new in 1.24
164
+ Enabled: true
165
+ Style/HashConversion: # new in 1.10
166
+ Enabled: true
167
+ Style/HashExcept: # new in 1.7
168
+ Enabled: true
169
+ Style/HashFetchChain: # new in 1.75
170
+ Enabled: true
171
+ Style/HashSlice: # new in 1.71
172
+ Enabled: true
173
+ Style/IfWithBooleanLiteralBranches: # new in 1.9
174
+ Enabled: true
175
+ Style/InPatternThen: # new in 1.16
176
+ Enabled: true
177
+ Style/ItAssignment: # new in 1.70
178
+ Enabled: true
179
+ Style/ItBlockParameter: # new in 1.75
180
+ Enabled: true
181
+ Style/KeywordArgumentsMerging: # new in 1.68
182
+ Enabled: true
183
+ Style/MagicCommentFormat: # new in 1.35
184
+ Enabled: true
185
+ Style/MapCompactWithConditionalBlock: # new in 1.30
186
+ Enabled: true
187
+ Style/MapIntoArray: # new in 1.63
188
+ Enabled: true
189
+ Style/MapToHash: # new in 1.24
190
+ Enabled: true
191
+ Style/MapToSet: # new in 1.42
192
+ Enabled: true
193
+ Style/MinMaxComparison: # new in 1.42
194
+ Enabled: true
195
+ Style/MultilineInPatternThen: # new in 1.16
196
+ Enabled: true
197
+ Style/NegatedIfElseCondition: # new in 1.2
198
+ Enabled: true
199
+ Style/NestedFileDirname: # new in 1.26
200
+ Enabled: true
201
+ Style/NilLambda: # new in 1.3
202
+ Enabled: true
203
+ Style/NumberedParameters: # new in 1.22
204
+ Enabled: true
205
+ Style/NumberedParametersLimit: # new in 1.22
206
+ Enabled: true
207
+ Style/ObjectThen: # new in 1.28
208
+ Enabled: true
209
+ Style/OpenStructUse: # new in 1.23
210
+ Enabled: true
211
+ Style/OperatorMethodCall: # new in 1.37
212
+ Enabled: true
213
+ Style/QuotedSymbols: # new in
214
+ Enabled: true
data/README.md CHANGED
@@ -6,51 +6,62 @@
6
6
 
7
7
  ## Usage in the code
8
8
 
9
+ project = random_name
9
10
  name = Rujira::Api::Myself.get.name
10
- Rujira::Api::Project.get 'ITMG'
11
+ Rujira::Api::Project.create do
12
+ data key: project.to_s,
13
+ name: project.to_s,
14
+ projectTypeKey: 'software',
15
+ lead: 'root'
16
+ end
17
+ Rujira::Api::Project.get project.to_s
11
18
  Rujira::Api::Issue.create do
12
- data fields: {
13
- project: { key: 'ITMG' },
14
- summary: 'BOT: added a new feature.',
15
- description: 'This task was generated by the bot when creating changes in the repository.',
16
- issuetype: { name: 'Task' },
17
- labels: ['bot'] }
18
- params updateHistory: true
19
+ data fields: {
20
+ project: { key: project.to_s },
21
+ summary: 'BOT: added a new feature.',
22
+ description: 'This task was generated by the bot when creating changes in the repository.',
23
+ issuetype: { name: 'Task' }
24
+ }
25
+ params updateHistory: true
19
26
  end
20
- Rujira::Api::Issue.watchers 'ITMG-1', 'wilful'
21
- Rujira::Api::Issue.get 'ITMG-1'
27
+ Rujira::Api::Issue.watchers "#{project}-1", name
28
+ Rujira::Api::Issue.get "#{project}-1"
22
29
  result = Rujira::Api::Search.get do
23
- data jql: 'project = ITMG and status IN ("To Do", "In Progress") ORDER BY issuekey',
24
- maxResults: 10,
25
- startAt: 0,
26
- fields: ['id', 'key']
30
+ data jql: "project = #{project} and status IN (\"To Do\", \"In Progress\") ORDER BY issuekey",
31
+ maxResults: 10,
32
+ startAt: 0,
33
+ fields: %w[id key]
34
+ end
35
+ Rujira::Api::Issue.comment "#{project}-1" do
36
+ data body: 'Adding a new comment'
27
37
  end
28
- result.iter
29
- Rujira::Api::Issue.comment 'ITMG-1' do
30
- data body: 'Adding a new comment'
38
+ Rujira::Api::Issue.edit "#{project}-1" do
39
+ data update: {
40
+ labels: [{ add: 'bot' }, { remove: 'some' }]
41
+ },
42
+ fields: {
43
+ assignee: { name: name },
44
+ summary: 'This is a shorthand for a set operation on the summary field'
45
+ }
31
46
  end
32
- Rujira::Api::Issue.edit 'ITMG-1' do
33
- data update: {
34
- labels:[{add: 'rujira'},{remove: 'bot'}],
35
- },
36
- fields: {
37
- assignee: { name: name },
38
- summary: 'This is a shorthand for a set operation on the summary field'
39
- }
47
+ result.iter.each do |issue|
48
+ Rujira::Api::Issue.del issue.data['id'] do
49
+ params deleteSubtasks: true
50
+ end
40
51
  end
41
- Rujira::Api::Issue.attachments 'ITMG-1', 'upload.png'
42
- Rujira::Api::Issue.del 'ITMG-1'
43
52
 
44
53
  ## Rake tasks
45
54
 
46
55
  require 'rujira/tasks/jira'
47
- rake jira::whoami
48
- rake jira:create -- '--project=ITMG' \
56
+ Rujira::Tasks::Jira.new
57
+
58
+ rake jira:issue:whoami
59
+ rake jira:issue:create -- '--project=ITMG' \
49
60
  '--summary=The short summary information' \
50
61
  '--description=The base description of task' \
51
62
  '--issuetype=Task'
52
- rake jira:search -- '-q project = ITMG'
53
- rake jira:attach -- '--file=upload.png' '--issue=ITMG-1'
63
+ rake jira:issue:search -- '-q project = ITMG'
64
+ rake jira:issue:attach -- '--file=upload.png' '--issue=ITMG-1'
54
65
 
55
66
  ## Testing
56
67
 
data/Rakefile CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'bundler/gem_tasks'
4
4
  require 'rake/testtask'
5
+ require 'dotenv'
6
+ Dotenv.load
5
7
 
6
8
  $LOAD_PATH.unshift File.expand_path('lib', __dir__)
7
9
  require 'rujira'
data/compose.yaml CHANGED
@@ -1,5 +1,4 @@
1
1
  ---
2
- version: '3'
3
2
  services:
4
3
  jira:
5
4
  restart: always
@@ -9,7 +8,18 @@ services:
9
8
  ports:
10
9
  - 8080:8080
11
10
  volumes:
12
- - 'data:/var/atlassian/application-data/jira'
11
+ - 'jira-data:/var/atlassian/application-data/jira'
12
+
13
+ db:
14
+ image: postgres
15
+ restart: always
16
+ shm_size: 128mb
17
+ environment:
18
+ POSTGRES_PASSWORD: postgres
19
+ POSTGRES_DB: jira
20
+ volumes:
21
+ - 'db-data:/var/lib/postgresql/data'
13
22
 
14
23
  volumes:
15
- data:
24
+ jira-data:
25
+ db-data:
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rujira'
4
+ require 'uri'
5
+
6
+ class JiraLinkGenerator
7
+ attr_reader :uri
8
+
9
+ def initialize(host)
10
+ @host = host
11
+ @uri = URI.parse("#{host}/secure/CreateIssueDetails!init.jspa")
12
+ end
13
+
14
+ def params(hash)
15
+ @uri.query = URI.encode_www_form(hash)
16
+
17
+ self
18
+ end
19
+
20
+ def generate
21
+ puts 'Enter project ID (pid):'
22
+ pid = gets.strip
23
+
24
+ puts 'Enter issue type ID (issuetypeid):'
25
+ issuetypeid = gets.strip
26
+
27
+ puts 'Enter issue summary:'
28
+ summary = gets.strip
29
+
30
+ puts 'Enter priority ID (e.g. 1–5):'
31
+ priority = gets.strip
32
+
33
+ puts 'Enter issue description:'
34
+ description = gets.strip
35
+
36
+ params({
37
+ pid: pid,
38
+ issuetypeid: issuetypeid,
39
+ summary: summary,
40
+ priority: priority,
41
+ description: description
42
+ })
43
+ end
44
+ end
45
+
46
+ builder = JiraLinkGenerator.new('https://jira.domain.org')
47
+ .params({ pid: 15_750, issuetypeid: 3, summary: 'Test', priority: 5, description: 'Test' })
48
+ builder = JiraLinkGenerator.new('https://jira.domain.org').generate
49
+ pp builder.uri.to_s
@@ -3,7 +3,7 @@
3
3
  module Rujira
4
4
  module Api
5
5
  # TODO
6
- # https://docs.atlassian.com/software/jira/docs/api/REST/8.17.1/#api/2/comment/%7BcommentId%7D/properties
7
- class Attachments < Item; end
6
+ # https://docs.atlassian.com/software/jira/docs/api/REST/9.17.0/#api/2/comment/%7BcommentId%7D/properties
7
+ class Attachments < Common; end
8
8
  end
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Rujira
4
4
  module Api
5
5
  # TODO
6
- # https://docs.atlassian.com/software/jira/docs/api/REST/8.17.1/#api/2/comment/%7BcommentId%7D/properties
7
- class Comment < Item; end
6
+ # https://docs.atlassian.com/software/jira/docs/api/REST/9.17.0/#api/2/comment/%7BcommentId%7D/properties
7
+ class Comment < Common; end
8
8
  end
9
9
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rujira
4
+ module Api
5
+ # TODO
6
+ class Common
7
+ attr_reader :data
8
+
9
+ def initialize(data = nil)
10
+ @data = data
11
+ end
12
+
13
+ def self.rq
14
+ Request.new.builder do
15
+ bearer Configuration.token
16
+ end
17
+ end
18
+
19
+ def self.method_missing(method, *_args)
20
+ method = [method.to_sym]
21
+ raise "The method #{method} does not exist.
22
+ The following methods are available: #{methods(false)}"
23
+ end
24
+
25
+ def self.respond_to_missing?(method, include_private = false)
26
+ methods.include?(method) || super
27
+ end
28
+ end
29
+ end
30
+ end
@@ -3,72 +3,72 @@
3
3
  module Rujira
4
4
  module Api
5
5
  # TODO
6
- # https://docs.atlassian.com/software/jira/docs/api/REST/8.17.1/#api/2/issue
7
- class Issue < Item
6
+ # https://docs.atlassian.com/software/jira/docs/api/REST/9.17.0/#api/2/issue
7
+ class Issue < Common
8
8
  def self.create(&block)
9
- entity = Entity.build do
9
+ rq = self.rq.builder do
10
10
  path 'issue'
11
- method :POST
11
+ method :post
12
12
  instance_eval(&block) if block_given?
13
13
  end
14
- new(entity.commit)
14
+ new(rq.commit)
15
15
  end
16
16
 
17
17
  def self.get(id_or_key, &block)
18
- entity = Entity.build do
18
+ rq = self.rq.builder do
19
19
  path "issue/#{id_or_key}"
20
20
  instance_eval(&block) if block_given?
21
21
  end
22
- new(entity.commit)
22
+ new(rq.commit)
23
23
  end
24
24
 
25
25
  def self.del(id_or_key, &block)
26
- entity = Entity.build do
26
+ rq = self.rq.builder do
27
27
  path "issue/#{id_or_key}"
28
- method :DELETE
28
+ method :delete
29
29
  instance_eval(&block) if block_given?
30
30
  end
31
- entity.commit
31
+ rq.commit
32
32
  end
33
33
 
34
34
  def self.edit(id_or_key, &block)
35
- entity = Entity.build do
35
+ rq = self.rq.builder do
36
36
  path "issue/#{id_or_key}"
37
- method :PUT
37
+ method :put
38
38
  instance_eval(&block) if block_given?
39
39
  end
40
- new(entity.commit)
40
+ new(rq.commit)
41
41
  end
42
42
 
43
43
  def self.comment(id_or_key, &block)
44
- entity = Entity.build do
44
+ rq = self.rq.builder do
45
45
  path "issue/#{id_or_key}/comment"
46
- method :POST
46
+ method :post
47
47
  instance_eval(&block) if block_given?
48
48
  end
49
- Comment.new(entity.commit)
49
+ Comment.new(rq.commit)
50
50
  end
51
51
 
52
52
  def self.watchers(id_or_key, name, &block)
53
- entity = Entity.build do
53
+ rq = self.rq.builder do
54
54
  path "issue/#{id_or_key}/watchers"
55
- method :POST
55
+ method :post
56
56
  data name.to_json
57
57
  instance_eval(&block) if block_given?
58
58
  end
59
- new(entity.commit)
59
+ new(rq.commit)
60
60
  end
61
61
 
62
62
  def self.attachments(id_or_key, path, &block)
63
- entity = Entity.build do
63
+ rq = self.rq.builder do
64
64
  path "issue/#{id_or_key}/attachments"
65
- method :POST
65
+ method :post
66
66
  headers 'Content-Type': 'multipart/form-data', 'X-Atlassian-Token': 'nocheck',
67
67
  'Transfer-Encoding': 'chunked', 'Content-Length': File.size(path).to_s
68
68
  data file: Faraday::Multipart::FilePart.new(path, 'multipart/form-data')
69
69
  instance_eval(&block) if block_given?
70
70
  end
71
- Attachments.new(entity.commit)
71
+ Attachments.new(rq.commit)
72
72
  end
73
73
  end
74
74
  end
@@ -3,13 +3,13 @@
3
3
  module Rujira
4
4
  module Api
5
5
  # TODO
6
- # https://docs.atlassian.com/software/jira/docs/api/REST/8.17.1/#api/2/myself
7
- class Myself < Item
6
+ # https://docs.atlassian.com/software/jira/docs/api/REST/9.17.0/#api/2/myself
7
+ class Myself < Common
8
8
  def self.get
9
- entity = Entity.build do
9
+ rq = self.rq.builder do
10
10
  path 'myself'
11
11
  end
12
- new(entity.commit)
12
+ new(rq.run)
13
13
  end
14
14
 
15
15
  def name
@@ -3,22 +3,40 @@
3
3
  module Rujira
4
4
  module Api
5
5
  # TODO
6
- # https://docs.atlassian.com/software/jira/docs/api/REST/8.17.1/#api/2/project
7
- class Project < Item
6
+ # https://docs.atlassian.com/software/jira/docs/api/REST/9.17.0/#api/2/project
7
+ class Project < Common
8
+ def self.create(&block)
9
+ rq = self.rq.builder do
10
+ path 'project'
11
+ method :post
12
+ instance_eval(&block) if block_given?
13
+ end
14
+ new(rq.commit)
15
+ end
16
+
17
+ def self.edit(id_or_key, &block)
18
+ rq = self.rq.builder do
19
+ path "project/#{id_or_key}"
20
+ method :put
21
+ instance_eval(&block) if block_given?
22
+ end
23
+ new(rq.commit)
24
+ end
25
+
8
26
  def self.get(id_or_key, &block)
9
- entity = Entity.build do
27
+ rq = self.rq.builder do
10
28
  path "project/#{id_or_key}"
11
29
  instance_eval(&block) if block_given?
12
30
  end
13
- new(entity.commit)
31
+ new(rq.commit)
14
32
  end
15
33
 
16
34
  def self.securitylevel(id_or_key, &block)
17
- entity = Entity.build do
35
+ rq = self.rq.builder do
18
36
  path "project/#{id_or_key}/securitylevel"
19
37
  instance_eval(&block) if block_given?
20
38
  end
21
- new(entity.commit)
39
+ new(rq.commit)
22
40
  end
23
41
  end
24
42
  end
@@ -3,15 +3,15 @@
3
3
  module Rujira
4
4
  module Api
5
5
  # TODO
6
- # https://docs.atlassian.com/software/jira/docs/api/REST/8.17.1/#api/2/search
7
- class Search < Item
6
+ # https://docs.atlassian.com/software/jira/docs/api/REST/9.17.0/#api/2/search
7
+ class Search < Common
8
8
  def self.get(&block)
9
- entity = Entity.build do
9
+ rq = self.rq.builder do
10
10
  path 'search'
11
- method :POST
11
+ method :post
12
12
  instance_eval(&block) if block_given?
13
13
  end
14
- new(entity.commit)
14
+ new((rq.commit))
15
15
  end
16
16
 
17
17
  def iter
@@ -3,13 +3,13 @@
3
3
  module Rujira
4
4
  module Api
5
5
  # TODO
6
- # https://docs.atlassian.com/software/jira/docs/api/REST/8.17.1/#api/2/serverInfo
7
- class ServerInfo < Item
6
+ # https://docs.atlassian.com/software/jira/docs/api/REST/9.17.0/#api/2/serverInfo
7
+ class ServerInfo < Common
8
8
  def self.get
9
- entity = Entity.build do
9
+ rq = self.rq.builder do
10
10
  path 'serverInfo'
11
11
  end
12
- new(entity.commit)
12
+ new(rq.commit)
13
13
  end
14
14
  end
15
15
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rujira
4
+ class Error < StandardError; end
5
+
6
+ # TODO
7
+ class PathArgumentError < Error
8
+ def message
9
+ "No argument to 'path' was given."
10
+ end
11
+ end
12
+
13
+ # TODO
14
+ class DataArgumentError < Error
15
+ def message
16
+ "No argument to 'data' was given."
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'async/http/faraday'
4
+
5
+ module Rujira
6
+ # TODO
7
+ class Request
8
+ def initialize
9
+ @token = Configuration.token
10
+ @debug = Configuration.debug
11
+ @options = {
12
+ url: Configuration.url
13
+ }
14
+ @method = :get
15
+ @params = {}
16
+ @headers = {}
17
+ @payload = nil
18
+ @base_uri = 'rest/api/2'
19
+ @authorization = nil
20
+ @path = nil
21
+ end
22
+
23
+ def builder(&block)
24
+ return self unless block_given?
25
+
26
+ instance_eval(&block)
27
+ self
28
+ end
29
+
30
+ alias build builder
31
+
32
+ def params(params)
33
+ @params = params
34
+ end
35
+
36
+ def headers(headers)
37
+ @headers = headers
38
+ end
39
+
40
+ def method(method)
41
+ @method = method
42
+ end
43
+
44
+ def bearer(token)
45
+ @authorization = 'Bearer', -> { token }
46
+ end
47
+
48
+ def basic(username, password)
49
+ @authorization = :basic, username, password
50
+ end
51
+
52
+ def path(path)
53
+ raise PathArgumentError if path.nil?
54
+
55
+ @path = "#{@base_uri}/#{path}"
56
+
57
+ @path if @path
58
+ end
59
+
60
+ def payload(payload)
61
+ @payload = payload
62
+
63
+ @payload if @payload
64
+ end
65
+
66
+ alias data payload
67
+
68
+ def run
69
+ send(@method.downcase).body
70
+ end
71
+
72
+ alias commit run
73
+
74
+ private
75
+
76
+ def request
77
+ yield
78
+ rescue Faraday::Error => e
79
+ raise "Status #{e.response[:status]}: #{e.response[:body]}"
80
+ end
81
+
82
+ def get
83
+ request do
84
+ client.get @path do |req|
85
+ req.headers = @headers
86
+ req.params = @params
87
+ req.body = @payload
88
+ end
89
+ end
90
+ end
91
+
92
+ def delete
93
+ request do
94
+ client.delete @path do |req|
95
+ req.headers = @headers
96
+ req.params = @params
97
+ req.body = @payload
98
+ end
99
+ end
100
+ end
101
+
102
+ def post
103
+ request do
104
+ client.post @path do |req|
105
+ req.headers = @headers
106
+ req.params = @params
107
+ req.body = @payload
108
+ end
109
+ end
110
+ end
111
+
112
+ def put
113
+ request do
114
+ client.put @path do |req|
115
+ req.headers = @headers
116
+ req.params = @params
117
+ req.body = @payload
118
+ end
119
+ end
120
+ end
121
+
122
+ def client
123
+ Faraday.new(@options) do |builder|
124
+ builder.adapter :async_http
125
+ builder.request :authorization, *@authorization if @authorization
126
+ builder.request :multipart, flat_encode: true
127
+ builder.request :json
128
+ builder.response :json
129
+ builder.response :raise_error
130
+ builder.response :logger if @debug
131
+ end
132
+ end
133
+ end
134
+ end
@@ -15,7 +15,8 @@ module Rujira
15
15
  issuetype: 'Task'
16
16
  }
17
17
  @parser = OptionParser.new
18
- define
18
+
19
+ apply
19
20
  end
20
21
 
21
22
  def parser
@@ -30,84 +31,93 @@ module Rujira
30
31
 
31
32
  # rubocop:disable Metrics/AbcSize
32
33
  # rubocop:disable Metrics/MethodLength
33
- def define
34
- generate 'whoami' do
35
- puts Rujira::Api::Myself.get.name
36
- end
37
- generate 'url' do
38
- puts Rujira::Configuration.url
39
- end
40
- generate 'server_info' do
41
- puts Rujira::Api::ServerInfo.get.data.to_json
42
- end
43
- generate 'create' do
44
- parser do
45
- @parser.banner = "Usage: rake jira:task:create -- '[options]'"
46
- @parser.on('-p PROJECT', '--project=PROJECT') { |project| @options[:project] = project.strip }
47
- @parser.on('-s SUMMARY', '--summary=SUMMARY') { |summary| @options[:summary] = summary.strip }
48
- @parser.on('-d DESCRIPTION', '--description=DESCRIPTION') do |description|
49
- @options[:description] = description.strip
50
- end
51
- @parser.on('-i ISSUETYPE', '--issuetype=ISSUETYPE') { |issuetype| @options[:issuetype] = issuetype.strip }
34
+ # rubocop:disable Metrics/BlockLength
35
+ def apply
36
+ namespace :jira do
37
+ desc 'Test connection by getting username'
38
+ task :whoami do
39
+ puts Rujira::Api::Myself.get.name
52
40
  end
53
41
 
54
- options = @options
55
- result = Rujira::Api::Issue.create do
56
- data fields: {
57
- project: { key: options[:project] },
58
- summary: options[:summary],
59
- issuetype: { name: options[:issuetype] },
60
- description: options[:description]
61
- }
62
- end
63
- url = Rujira::Configuration.url
64
- puts "// A new task been posted, check it out at #{url}/browse/#{result.data['key']}"
65
- end
66
- generate 'search' do
67
- parser do
68
- @parser.banner = "Usage: rake jira:task:search -- '[options]'"
69
- @parser.on('-q JQL', '--jql=JQL') { |jql| @options[:jql] = jql }
42
+ desc 'Test connection by getting url'
43
+ task :url do
44
+ puts Rujira::Configuration.url
70
45
  end
71
46
 
72
- options = @options
73
- result = Rujira::Api::Search.get do
74
- data jql: options[:jql]
75
- end
76
- result.iter.each { |i| puts JSON.pretty_generate(i.data) }
77
- end
78
- generate 'delete' do
79
- parser do
80
- @parser.banner = "Usage: rake jira:task:delete -- '[options]'"
81
- @parser.on('-i ID', '--issue=ID') { |id| @options[:id] = id }
47
+ desc 'Test connection by getting server information'
48
+ task :server_info do
49
+ puts Rujira::Api::ServerInfo.get.data.to_json
82
50
  end
83
51
 
84
- Rujira::Api::Issue.del @options[:id]
85
- end
86
- generate 'attach' do
87
- parser do
88
- @parser.banner = "Usage: rake jira:task:attach -- '[options]'"
89
- @parser.on('-f FILE', '--file=FILE') { |file| @options[:file] = file }
90
- @parser.on('-i ID', '--issue=ID') { |id| @options[:id] = id }
91
- end
52
+ namespace :issue do
53
+ desc 'Create a issue'
54
+ task :create do
55
+ parser do
56
+ @parser.banner = "Usage: rake jira:issue:create -- '[options]'"
57
+ @parser.on('-p PROJECT', '--project=PROJECT') { |project| @options[:project] = project.strip }
58
+ @parser.on('-s SUMMARY', '--summary=SUMMARY') { |summary| @options[:summary] = summary.strip }
59
+ @parser.on('-d DESCRIPTION', '--description=DESCRIPTION') do |description|
60
+ @options[:description] = description.strip
61
+ end
62
+ @parser.on('-i ISSUETYPE', '--issuetype=ISSUETYPE') do |issuetype|
63
+ @options[:issuetype] = issuetype.strip
64
+ end
65
+ end
92
66
 
93
- result = Rujira::Api::Issue.attachments @options[:id], @options[:file]
94
- puts JSON.pretty_generate(result.data)
95
- end
96
- end
97
- # rubocop:enable Metrics/AbcSize
98
- # rubocop:enable Metrics/MethodLength
67
+ options = @options
68
+ result = Rujira::Api::Issue.create do
69
+ data fields: {
70
+ project: { key: options[:project] },
71
+ summary: options[:summary],
72
+ issuetype: { name: options[:issuetype] },
73
+ description: options[:description]
74
+ }
75
+ end
76
+ url = Rujira::Configuration.url
77
+ puts "// A new issue been posted, check it out at #{url}/browse/#{result.data['key']}"
78
+ end
99
79
 
100
- def generate(name, &block)
101
- fullname = "jira:#{name}"
102
- desc "Run #{fullname}"
80
+ desc 'Search issue by fields'
81
+ task :search do
82
+ parser do
83
+ @parser.banner = "Usage: rake jira:issue:search -- '[options]'"
84
+ @parser.on('-q JQL', '--jql=JQL') { |jql| @options[:jql] = jql }
85
+ end
103
86
 
104
- Rake::Task[fullname].clear if Rake::Task.task_defined?(fullname)
105
- namespace :jira do
106
- task name do
107
- instance_eval(&block)
87
+ options = @options
88
+ result = Rujira::Api::Search.get do
89
+ data jql: options[:jql]
90
+ end
91
+ result.iter.each { |i| puts JSON.pretty_generate(i.data) }
92
+ end
93
+
94
+ desc 'Delete issue'
95
+ task :delete do
96
+ parser do
97
+ @parser.banner = "Usage: rake jira:issue:delete -- '[options]'"
98
+ @parser.on('-i ID', '--issue=ID') { |id| @options[:id] = id }
99
+ end
100
+
101
+ Rujira::Api::Issue.del @options[:id]
102
+ end
103
+
104
+ desc 'Example usage attaching in issue'
105
+ task :attach do
106
+ parser do
107
+ @parser.banner = "Usage: rake jira:issue:attach -- '[options]'"
108
+ @parser.on('-f FILE', '--file=FILE') { |file| @options[:file] = file }
109
+ @parser.on('-i ID', '--issue=ID') { |id| @options[:id] = id }
110
+ end
111
+
112
+ result = Rujira::Api::Issue.attachments @options[:id], @options[:file]
113
+ puts JSON.pretty_generate(result.data)
114
+ end
108
115
  end
109
116
  end
110
117
  end
118
+ # rubocop:enable Metrics/BlockLength
119
+ # rubocop:enable Metrics/AbcSize
120
+ # rubocop:enable Metrics/MethodLength
111
121
  end
112
122
  end
113
123
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rujira
4
- VERSION = "0.1.10"
4
+ VERSION = '0.1.14'
5
5
  end
data/lib/rujira.rb CHANGED
@@ -3,11 +3,11 @@
3
3
  require 'faraday'
4
4
  require 'faraday/multipart'
5
5
  require 'json'
6
+ require_relative 'rujira/error'
6
7
  require_relative 'rujira/version'
7
- require_relative 'rujira/connection'
8
8
  require_relative 'rujira/configuration'
9
- require_relative 'rujira/entity'
10
- require_relative 'rujira/api/item'
9
+ require_relative 'rujira/request'
10
+ require_relative 'rujira/api/common'
11
11
  require_relative 'rujira/api/search'
12
12
  require_relative 'rujira/api/issue'
13
13
  require_relative 'rujira/api/project'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rujira
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey Semenov
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-07-05 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: faraday
@@ -45,24 +44,26 @@ executables: []
45
44
  extensions: []
46
45
  extra_rdoc_files: []
47
46
  files:
47
+ - ".rubocop.yml"
48
48
  - CHANGELOG.md
49
49
  - CODE_OF_CONDUCT.md
50
50
  - LICENSE.txt
51
51
  - README.md
52
52
  - Rakefile
53
53
  - compose.yaml
54
+ - contrib/jira_link_generator.rb
54
55
  - lib/rujira.rb
55
56
  - lib/rujira/api/attachments.rb
56
57
  - lib/rujira/api/comment.rb
58
+ - lib/rujira/api/common.rb
57
59
  - lib/rujira/api/issue.rb
58
- - lib/rujira/api/item.rb
59
60
  - lib/rujira/api/myself.rb
60
61
  - lib/rujira/api/project.rb
61
62
  - lib/rujira/api/search.rb
62
63
  - lib/rujira/api/server_info.rb
63
64
  - lib/rujira/configuration.rb
64
- - lib/rujira/connection.rb
65
- - lib/rujira/entity.rb
65
+ - lib/rujira/error.rb
66
+ - lib/rujira/request.rb
66
67
  - lib/rujira/tasks/jira.rb
67
68
  - lib/rujira/version.rb
68
69
  - sig/rujira.rbs
@@ -71,7 +72,6 @@ licenses:
71
72
  - MIT
72
73
  metadata:
73
74
  homepage_uri: https://github.com/itmagelabs/rujira
74
- post_install_message:
75
75
  rdoc_options: []
76
76
  require_paths:
77
77
  - lib
@@ -86,8 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  - !ruby/object:Gem::Version
87
87
  version: '0'
88
88
  requirements: []
89
- rubygems_version: 3.5.10
90
- signing_key:
89
+ rubygems_version: 3.6.8
91
90
  specification_version: 4
92
91
  summary: API for Atlassian jira in ruby
93
92
  test_files: []
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rujira
4
- module Api
5
- # TODO
6
- class Item
7
- attr_reader :data
8
-
9
- def initialize(data = nil)
10
- @data = data
11
- end
12
- end
13
- end
14
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rujira
4
- # TODO
5
- class Connection
6
- def initialize
7
- @token = Configuration.token
8
- @options = {
9
- url: Configuration.url
10
- }
11
- end
12
-
13
- def run
14
- Faraday.new(@options) do |builder|
15
- builder.request :authorization, 'Bearer', -> { @token }
16
- builder.request :multipart, flat_encode: true
17
- builder.request :json
18
- builder.response :json
19
- builder.response :raise_error
20
- builder.response :logger if Configuration.debug
21
- end
22
- end
23
- end
24
- end
data/lib/rujira/entity.rb DELETED
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Rujira
4
- # TODO
5
- class Entity
6
- def initialize
7
- @method = :GET
8
- @params = {}
9
- @headers = {}
10
- @rest_api = 'rest/api/2'
11
- end
12
-
13
- def self.build(&block)
14
- entity = new
15
- return entity unless block_given?
16
-
17
- entity.instance_eval(&block)
18
-
19
- entity
20
- end
21
-
22
- def params(params)
23
- @params = params
24
- end
25
-
26
- def headers(headers)
27
- @headers = headers
28
- end
29
-
30
- def method(method)
31
- @method = method
32
- end
33
-
34
- def path(path = nil)
35
- @path ||= "#{@rest_api}/#{path}"
36
-
37
- return @path if @path
38
-
39
- raise ArgumentError, "No argument to 'path' was given."
40
- end
41
-
42
- def data(data = nil)
43
- @data ||= data
44
-
45
- return @data if @data
46
-
47
- raise ArgumentError, "No argument to 'data' was given."
48
- end
49
-
50
- def commit
51
- case @method
52
- when :GET
53
- get.body
54
- when :PUT
55
- put.body
56
- when :POST
57
- post.body
58
- when :DELETE
59
- delete.body
60
- end
61
- end
62
-
63
- private
64
-
65
- def request
66
- yield
67
- rescue Faraday::Error => e
68
- raise "Status #{e.response[:status]}: #{e.response[:body]}"
69
- end
70
-
71
- def get
72
- request do
73
- client.get path do |req|
74
- req.params = @params
75
- end
76
- end
77
- end
78
-
79
- def delete
80
- request do
81
- client.delete path do |req|
82
- req.params = @params
83
- end
84
- end
85
- end
86
-
87
- def post
88
- request do
89
- client.post path do |req|
90
- req.headers = @headers
91
- req.params = @params
92
- req.body = data
93
- end
94
- end
95
- end
96
-
97
- def put
98
- request do
99
- client.put path do |req|
100
- req.params = @params
101
- req.body = data
102
- end
103
- end
104
- end
105
-
106
- def client
107
- conn = Rujira::Connection.new
108
- conn.run
109
- end
110
- end
111
- end