tractive 1.0.14 → 1.0.15
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 +4 -4
- data/.rubocop.yml +1 -1
- data/exe/tractive +2 -0
- data/lib/tractive/github_api/graph_ql_client/issues.rb +29 -0
- data/lib/tractive/github_api/graph_ql_client.rb +31 -0
- data/lib/tractive/github_api.rb +1 -0
- data/lib/tractive/info.rb +13 -0
- data/lib/tractive/main.rb +3 -1
- data/lib/tractive/migrator/converter/trac_to_github.rb +15 -11
- data/lib/tractive/migrator/engine/migrate_from_db.rb +41 -0
- data/lib/tractive/migrator/engine.rb +2 -0
- data/lib/tractive/version.rb +1 -1
- data/tractive.gemspec +1 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cde84b7e5731a9be33bbbdecc11abacca397665fa29e4734c01bc50c1823c46
|
4
|
+
data.tar.gz: e38bd03de9ed35f8bde8c371c30789815f9fbecbe9b5cb8535c1585ad9f2e4e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e5fd7afc6dfab34b8514a3fa0d12eec6d98d697938a500f7142891c33fc5a4d5f32442da7503be59b112c361d7010e617fb6dab9f9f90b65d0917a98bded050
|
7
|
+
data.tar.gz: 2c0247ec8af3ac372f4244d9c8ac0c2b2dc0a1358f5be3d7619507640404b8db088b03e9c884fa3c4612ae160bfa97828fa41992c2d31e7470a45cdb736342dd
|
data/.rubocop.yml
CHANGED
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
|
data/lib/tractive/github_api.rb
CHANGED
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
|
-
|
106
|
-
|
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[
|
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
|
data/lib/tractive/version.rb
CHANGED
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.
|
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
|
+
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
|