tractive 1.0.13 → 1.0.17

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: 6b9a604e9dd1c9d05edc6ebb71730d1c1660c7f5fc478a99ce87597fe48b567e
4
- data.tar.gz: 6c70e06cd214b9b97d3ec17878774b5417ee3108f95b1ec09642179ca88c5c4a
3
+ metadata.gz: ead46f0c5389125439e3e887de0c60205625d751c86737ba4477e9967c4ae46e
4
+ data.tar.gz: d93dd5f42054afe56f91cb9fbbb7d1dac9a0fcf42bca4307ab18097135809758
5
5
  SHA512:
6
- metadata.gz: 67728d36b54a32045c49a69c873c49a63a87ac6242260f3eefe09c1511b88919af579fcffd4bc08919825606f99cbcdd12284f3c5d3b347adaf8226c6c770f57
7
- data.tar.gz: 0caa7b60a2620eca00de262cd0d122cfab88a9fe6737800c7a281d9d36dfb0b02368722608cf130fe9c6faf8caf579bc96db111c130866df7fade690f8504bb4
6
+ metadata.gz: e385bd618aa607da18e7fddb41c4ecedc5a91cf981332bc825a951c1267555f8c351ee83ba3481411e32fc809a0771b52248a3f4971ed6e281d23e477362153b
7
+ data.tar.gz: d3fcce3c20a4f5c004ed51d0548eb9f1b60f3bc70b78f8614fc02aa7fde2a47d522ec0e6afa410f7b6b4f02d6e4c73545167c44e53dc355bf4d27225cc8c2fc7
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/command_base.rb CHANGED
@@ -7,5 +7,7 @@ class CommandBase < Thor
7
7
  desc: "Name of the logfile to output logs to."
8
8
  class_option "config", type: :string, default: "tractive.config.yaml", banner: "<PATH>", aliases: "-c",
9
9
  desc: "Set the configuration file"
10
+ class_option "git-token", type: :string,
11
+ desc: "The access token for Github actions."
10
12
  class_option "verbose", type: :boolean, aliases: ["-v", "--verbose"], desc: "Verbose mode"
11
13
  end
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
@@ -8,6 +8,11 @@ module Tractive
8
8
  @opts = opts
9
9
  @cfg = YAML.load_file(@opts[:config])
10
10
 
11
+ @cfg["github"] ||= {}
12
+ @cfg["github"]["token"] = @opts["git-token"] if @opts["git-token"]
13
+
14
+ GithubApi::GraphQlClient.add_constants(@cfg["github"]["token"]) unless @opts[:info]
15
+
11
16
  Tractive::Utilities.setup_logger(output_stream: @opts[:logfile] || $stderr, verbose: @opts[:verbose])
12
17
  @db = Tractive::Utilities.setup_db!(@opts["trac-database-path"] || @cfg["trac"]["database"])
13
18
  rescue Sequel::DatabaseConnectionError, Sequel::AdapterNotFound, URI::InvalidURIError, Sequel::DatabaseError => e
@@ -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.gsub(" ", "_")])
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.13"
4
+ VERSION = "1.0.17"
5
5
  end
data/tractive.gemspec CHANGED
@@ -27,6 +27,8 @@ 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", "1.13.3"
31
+ spec.add_dependency "graphql-client"
30
32
  spec.add_dependency "mysql2"
31
33
  spec.add_dependency "ox"
32
34
  spec.add_dependency "rest-client"
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tractive
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.13
4
+ version: 1.0.17
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-24 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: graphql
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.13.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 1.13.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: graphql-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: mysql2
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -145,6 +173,8 @@ files:
145
173
  - lib/tractive/github_api/client/issues.rb
146
174
  - lib/tractive/github_api/client/labels.rb
147
175
  - lib/tractive/github_api/client/milestones.rb
176
+ - lib/tractive/github_api/graph_ql_client.rb
177
+ - lib/tractive/github_api/graph_ql_client/issues.rb
148
178
  - lib/tractive/graceful_quit.rb
149
179
  - lib/tractive/http/client.rb
150
180
  - lib/tractive/http/client/request.rb