tractive 1.0.14 → 1.0.15

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0db013dccdcc48d417706b5f52036b4c5801b4d81d6a835c09ee4b1afc6480db
4
- data.tar.gz: 4603e9e32107e75a4e2f495dc4a93cbc4e810a65c2bee576721e7d58d4be78cd
3
+ metadata.gz: 8cde84b7e5731a9be33bbbdecc11abacca397665fa29e4734c01bc50c1823c46
4
+ data.tar.gz: e38bd03de9ed35f8bde8c371c30789815f9fbecbe9b5cb8535c1585ad9f2e4e5
5
5
  SHA512:
6
- metadata.gz: 5cf948f6fd3aed7f3b67778e91e9d88e7e1f9586824e21c4a1a0a4a42b42a14eedac4df7d5bf7627e182741ccf35865e195c1990c18e008b352b43bee08d4f4a
7
- data.tar.gz: f2b76c16fdf603a4d084df7a895f6ffdef16b4fc9297e6f039d9894e4b95a14a6d31ef090399983f46e68f4b904485df41102f3749926aef8adffee8e7d4011a
6
+ metadata.gz: 8e5fd7afc6dfab34b8514a3fa0d12eec6d98d697938a500f7142891c33fc5a4d5f32442da7503be59b112c361d7010e617fb6dab9f9f90b65d0917a98bded050
7
+ data.tar.gz: 2c0247ec8af3ac372f4244d9c8ac0c2b2dc0a1358f5be3d7619507640404b8db088b03e9c884fa3c4612ae160bfa97828fa41992c2d31e7470a45cdb736342dd
data/.rubocop.yml CHANGED
@@ -36,7 +36,7 @@ Metrics/MethodLength:
36
36
  Enabled: false
37
37
 
38
38
  Metrics/ModuleLength:
39
- Max: 150
39
+ Max: 250
40
40
 
41
41
  Metrics/ParameterLists:
42
42
  Max: 6
data/exe/tractive CHANGED
@@ -47,6 +47,8 @@ class TractiveCommand < CommandBase
47
47
  desc: "Put all issue comments in the first message."
48
48
  method_option "start", type: :numeric, aliases: ["-s", "--start-at"], banner: "<ID>",
49
49
  desc: "Start migration from ticket with number <ID>"
50
+ method_option "make-owners-labels", type: :boolean,
51
+ desc: "If true, this will make a tag like `owner:<owner name>` and add it to the issue."
50
52
  def migrate_tickets
51
53
  Tractive::Main.new(options).run
52
54
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GithubApi
4
+ class GraphQlClient
5
+ # Methods for the Issues API
6
+ module Issues
7
+ DELETE_ISSUE_QUERY = <<~QUERY
8
+ mutation ($input: DeleteIssueInput!) {
9
+ deleteIssue(input: $input) {
10
+ repository {
11
+ name
12
+ url
13
+ }
14
+ }
15
+ }
16
+ QUERY
17
+
18
+ def delete_issue(issue_id)
19
+ variables = {
20
+ "input" => {
21
+ "issueId" => issue_id
22
+ }
23
+ }
24
+
25
+ Client.query(DeleteIssueQuery, variables: variables)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "graph_ql_client/issues"
4
+
5
+ require "graphql/client"
6
+ require "graphql/client/http"
7
+
8
+ # Service to perform github actions
9
+ module GithubApi
10
+ class GraphQlClient
11
+ include GithubApi::GraphQlClient::Issues
12
+
13
+ HttpAdapter = GraphQL::Client::HTTP.new("https://api.github.com/graphql") do
14
+ attr_writer :token
15
+
16
+ def headers(_context)
17
+ {
18
+ "Authorization" => "bearer #{@token}"
19
+ }
20
+ end
21
+ end
22
+
23
+ def self.add_constants(token)
24
+ HttpAdapter.token = token
25
+
26
+ GithubApi::GraphQlClient.const_set("Schema", GraphQL::Client.load_schema(HttpAdapter))
27
+ GithubApi::GraphQlClient.const_set("Client", GraphQL::Client.new(schema: Schema, execute: HttpAdapter))
28
+ GithubApi::GraphQlClient.const_set("DeleteIssueQuery", Client.parse(DELETE_ISSUE_QUERY))
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "github_api/client"
4
+ require_relative "github_api/graph_ql_client"
data/lib/tractive/info.rb CHANGED
@@ -29,12 +29,25 @@ module Tractive
29
29
  priorities = Ticket.distinct.select(:priority).select_map(:priority).compact
30
30
  tracstates = Ticket.distinct.select(:status).select_map(:status).compact
31
31
 
32
+ keywords = Ticket.distinct
33
+ .select(:keywords)
34
+ .select_map(:keywords)
35
+ .map do |keyword|
36
+ keyword&.split(",")&.map do |k|
37
+ k.strip.gsub(" ", "_")
38
+ end
39
+ end
40
+ .flatten
41
+ .uniq
42
+ .compact
43
+
32
44
  {
33
45
  "users" => Utilities.make_each_hash(users, %w[email name username]),
34
46
  "milestones" => milestones,
35
47
  "labels" => {
36
48
  "type" => Utilities.make_hash("type_", types),
37
49
  "resolution" => Utilities.make_hash("resolution_", resolutions),
50
+ "keywords" => Utilities.make_hash("keyword_", keywords),
38
51
  "component" => Utilities.make_each_hash(components, %w[name color], "component: "),
39
52
  "severity" => Utilities.make_each_hash(severity, %w[name color]),
40
53
  "priority" => Utilities.make_each_hash(priorities, %w[name color]),
data/lib/tractive/main.rb CHANGED
@@ -9,7 +9,9 @@ module Tractive
9
9
  @cfg = YAML.load_file(@opts[:config])
10
10
 
11
11
  @cfg["github"] ||= {}
12
- @cfg["github"]["token"] = @opts["git-token"]
12
+ @cfg["github"]["token"] = @opts["git-token"] if @opts["git-token"]
13
+
14
+ GithubApi::GraphQlClient.add_constants(@cfg["github"]["token"]) unless @opts[:info]
13
15
 
14
16
  Tractive::Utilities.setup_logger(output_stream: @opts[:logfile] || $stderr, verbose: @opts[:verbose])
15
17
  @db = Tractive::Utilities.setup_db!(@opts["trac-database-path"] || @cfg["trac"]["database"])
@@ -16,6 +16,7 @@ module Migrator
16
16
  @client = GithubApi::Client.new(access_token: args[:cfg]["github"]["token"])
17
17
  @wiki_attachments_url = args[:cfg].dig("wiki", "attachments", "url")
18
18
  @revmap_file_path = args[:opts][:revmapfile] || args[:cfg]["revmap_path"]
19
+ @make_owners_label = args[:opts]["make-owners-labels"] || args[:cfg]["make_owners_labels"]
19
20
  @attachment_options = {
20
21
  url: @attachurl,
21
22
  hashed: args[:cfg].dig("ticket", "attachments", "hashed")
@@ -101,14 +102,11 @@ module Migrator
101
102
 
102
103
  labels.delete(nil)
103
104
 
104
- keywords = ticket[:keywords]
105
- if keywords
106
- if ticket[:keywords].downcase == "discuss"
107
- labels.add(@labels_cfg.fetch("keywords", {})[ticket[:keywords].downcase])
108
- else
109
- badges.add(@labels_cfg.fetch("keywords", {})[ticket[:keywords]])
110
- end
105
+ keywords = ticket[:keywords]&.split(",") || []
106
+ keywords.each do |keyword|
107
+ badges.add(@labels_cfg.fetch("keywords", {})[keyword.strip])
111
108
  end
109
+
112
110
  # If the field is not set, it will be nil and generate an unprocessable json
113
111
 
114
112
  milestone = @milestonemap[ticket[:milestone]]
@@ -121,6 +119,14 @@ module Migrator
121
119
 
122
120
  github_assignee = map_assignee(ticket[:owner])
123
121
 
122
+ unless github_assignee.nil? || github_assignee.empty?
123
+ if @make_owners_label
124
+ labels.add("name" => "owner:#{github_assignee}")
125
+ else
126
+ badges.add("owner:#{github_assignee}")
127
+ end
128
+ end
129
+
124
130
  badges = badges.to_a.compact.sort
125
131
  badgetable = badges.map { |i| %(`#{i}`) }.join(" ")
126
132
  badgetable += begin
@@ -132,8 +138,6 @@ module Migrator
132
138
 
133
139
  # compose body
134
140
  body = [badgetable, body, footer].join("\n\n___\n")
135
-
136
- labels.add("name" => "owner:#{github_assignee}") unless github_assignee.nil? || github_assignee.empty?
137
141
  labels = labels.map { |label| label["name"] }
138
142
 
139
143
  issue = {
@@ -265,7 +269,7 @@ module Migrator
265
269
  end
266
270
 
267
271
  case kind
268
- when "owner", "status", "title", "resolution", "priority", "component", "type", "severity", "platform", "milestone"
272
+ when "owner", "status", "title", "resolution", "priority", "component", "type", "severity", "platform", "milestone", "keywords"
269
273
  old = meta[:oldvalue]
270
274
  new = meta[:newvalue]
271
275
  if old && new
@@ -345,7 +349,7 @@ module Migrator
345
349
  end
346
350
 
347
351
  def interested_in_change?(kind, newvalue)
348
- !(%w[keywords cc reporter version].include?(kind) ||
352
+ !(%w[cc reporter version].include?(kind) ||
349
353
  (kind == "comment" && (newvalue.nil? || newvalue.lstrip.empty?)))
350
354
  end
351
355
 
@@ -23,6 +23,7 @@ module Migrator
23
23
  begin
24
24
  lasttracid = tractickets.last[:id]
25
25
  rescue StandardError
26
+ delete_mocked_tickets if can_delete_mocked_tickets?
26
27
  raise("trac has no ticket #{start_ticket}")
27
28
  end
28
29
 
@@ -89,6 +90,46 @@ module Migrator
89
90
 
90
91
  @last_created_issue = ticket[:id]
91
92
  end
93
+
94
+ delete_mocked_tickets if can_delete_mocked_tickets?
95
+ end
96
+
97
+ def can_delete_mocked_tickets?
98
+ @delete_mocked_tickets
99
+ end
100
+
101
+ def delete_mocked_tickets
102
+ page = 1
103
+ issues = @client.issues(@repo, { filter: "all",
104
+ state: "closed",
105
+ page: page })
106
+
107
+ until issues.empty?
108
+ deleted = false
109
+
110
+ issues.each do |issue|
111
+ next if issue["title"] != "Placeholder issue #{issue["number"]} created to align Github issue and trac ticket numbers during migration."
112
+
113
+ response = @graph_ql_client.delete_issue(issue["node_id"])
114
+
115
+ if response.data.errors.any?
116
+ error_message = response.data
117
+ .errors
118
+ .messages
119
+ .map { |k, v| "#{k}: #{v}" }
120
+ .join(", ")
121
+ raise StandardError, error_message
122
+ end
123
+
124
+ deleted = true
125
+ puts "Successfully deleted issue ##{issue["number"]}, Title: #{issue["title"]}"
126
+ end
127
+
128
+ page += 1 unless deleted
129
+ issues = @client.issues(@repo, { filter: "all",
130
+ state: "closed",
131
+ page: page })
132
+ end
92
133
  end
93
134
  end
94
135
  end
@@ -32,6 +32,7 @@ module Migrator
32
32
  @trac = Tractive::Trac.new(db)
33
33
  @repo = github["repo"]
34
34
  @client = GithubApi::Client.new(access_token: github["token"])
35
+ @graph_ql_client = GithubApi::GraphQlClient.new
35
36
 
36
37
  if input_file_name
37
38
  @from_file = input_file_name
@@ -62,6 +63,7 @@ module Migrator
62
63
  @safetychecks = safetychecks
63
64
  @start_ticket = (start_ticket || (@last_created_issue + 1)).to_i
64
65
  @filter_closed = filter_closed
66
+ @delete_mocked_tickets = args[:cfg]["ticket"]["delete_mocked"]
65
67
  end
66
68
 
67
69
  def migrate
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tractive
4
- VERSION = "1.0.14"
4
+ VERSION = "1.0.15"
5
5
  end
data/tractive.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
+ spec.add_dependency "graphql-client"
30
31
  spec.add_dependency "mysql2"
31
32
  spec.add_dependency "ox"
32
33
  spec.add_dependency "rest-client"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tractive
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.14
4
+ version: 1.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-11 00:00:00.000000000 Z
11
+ date: 2022-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: graphql-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: mysql2
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -145,6 +159,8 @@ files:
145
159
  - lib/tractive/github_api/client/issues.rb
146
160
  - lib/tractive/github_api/client/labels.rb
147
161
  - lib/tractive/github_api/client/milestones.rb
162
+ - lib/tractive/github_api/graph_ql_client.rb
163
+ - lib/tractive/github_api/graph_ql_client/issues.rb
148
164
  - lib/tractive/graceful_quit.rb
149
165
  - lib/tractive/http/client.rb
150
166
  - lib/tractive/http/client/request.rb