github_trello_importer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +66 -0
- data/bin/import-trello +55 -0
- data/github_trello_importer.gemspec +21 -0
- data/lib/importer.rb +11 -0
- data/lib/importer/cli.rb +38 -0
- data/lib/importer/error.rb +6 -0
- data/lib/importer/error_handler.rb +23 -0
- data/lib/importer/github.rb +27 -0
- data/lib/importer/import.rb +81 -0
- data/lib/importer/trello_issue_mapper.rb +9 -0
- data/lib/importer/version.rb +5 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1f4c971d242049aaf128baf764bb468e50f18dc4
|
4
|
+
data.tar.gz: dc9064366728eb83106448c9720bb0085759fcc4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc740b9e61a45fb59a2c64d3c19fa5584876e4181bae105a4df0c0b5565620a06b64b7aa1e259746d65c0c61982acefbb2d76083588cb9b4513976e1bf502f4a
|
7
|
+
data.tar.gz: 4afaca60c4213c6919371c1a2f18fe6c95d144c842aa4ca8baf1961c28f447891ddceff254b26cbe251aa8941d9ef70f7824fcdf9a4618d73f43132d5ca0a65a
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Scott Williams
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# GitHub Issue Exporter
|
2
|
+
|
3
|
+
[![Circle CI](https://circleci.com/gh/Tallwave/github_issue_exporter.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/Tallwave/github_issue_exporter) [![Code Climate](https://codeclimate.com/github/Tallwave/github_issue_exporter/badges/gpa.svg)](https://codeclimate.com/github/Tallwave/github_issue_exporter)
|
4
|
+
|
5
|
+
Trello is a good tool for quick data entry of user stories or issues, but it kinda sucks as a bug tracker. Fortunately it's easy to export cards from Trello in JSON, and GitHub's API makes it rather simple to create Issues from that.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
GitHub Trello Importer is built with Ruby and needs Ruby 2.0 or higher. Install it with RubyGems.
|
10
|
+
|
11
|
+
```
|
12
|
+
gem install github_trello_importer
|
13
|
+
```
|
14
|
+
|
15
|
+
Some environments may require `sudo` permissions.
|
16
|
+
|
17
|
+
```
|
18
|
+
sudo gem install github_trello_importer
|
19
|
+
```
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
There are two executables, `export-github-issues` and `import-github-issues`. Both reneed at least three things to run, the owner of the repository, the repository name, and an access token that has the authority to download the Issues. You can generate this token from [here](https://github.com/settings/tokens), and clicking on "Generate new token". Here's a [blog post with some more of the details involved](http://blog.swilliams.me/words/2015/04/01/two-factor-authentication-for-github/).
|
23
|
+
|
24
|
+
### export-github-issues
|
25
|
+
|
26
|
+
The Exporter has a couple of options.
|
27
|
+
|
28
|
+
`--multiple-files` By default Issue Exporter downloads and stores all the issues into a single JSON file. Setting the `multiple-files` flag will create a separate file for each Issue.
|
29
|
+
|
30
|
+
`--output` Set the directory to store the issues in. By default it is the current directory.
|
31
|
+
|
32
|
+
`--closed` By default, only Open issues are exported. Adding this flag will include Closed ones as well.
|
33
|
+
|
34
|
+
The issues will be exported into either a single `issues.json` file or multiple `issue-[NUMBER].json` files.
|
35
|
+
|
36
|
+
### Example
|
37
|
+
|
38
|
+
```
|
39
|
+
export-github-issues tallwave github_issue_exporter [TOKEN]
|
40
|
+
|
41
|
+
export-github-issues --closed tallwave github_issue_exporter [TOKEN]
|
42
|
+
|
43
|
+
export-github-issues --multiple-files --output ~/issues tallwave github_issue_exporter [TOKEN]
|
44
|
+
```
|
45
|
+
|
46
|
+
### import-github-issues
|
47
|
+
You can import issues a couple of different ways. First is to provide the name of each JSON file created by the exporter.
|
48
|
+
|
49
|
+
```
|
50
|
+
import-github-issues issues.json more-issues.json tallwave github_issue_exporter [TOKEN]
|
51
|
+
```
|
52
|
+
|
53
|
+
Or you can use the `--directory` flag and load all the JSON files in the specified directory.
|
54
|
+
|
55
|
+
```
|
56
|
+
import-github-issues --directory ~/issues tallwave github_issue_exporter [TOKEN]
|
57
|
+
```
|
58
|
+
|
59
|
+
## Roadmap
|
60
|
+
|
61
|
+
|
62
|
+
## Contributing
|
63
|
+
|
64
|
+
* Fork
|
65
|
+
* Make it better
|
66
|
+
* Create a Pull Request
|
data/bin/import-trello
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby -W
|
2
|
+
# Copyright (c) 2016 Tallwave
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
5
|
+
|
6
|
+
require "importer/cli"
|
7
|
+
|
8
|
+
module TrelloImporter
|
9
|
+
class Command
|
10
|
+
include CLI
|
11
|
+
|
12
|
+
def about
|
13
|
+
VERSION
|
14
|
+
end
|
15
|
+
|
16
|
+
def usage
|
17
|
+
<<HERE
|
18
|
+
Import a Trello export into GitHub issues.
|
19
|
+
|
20
|
+
Usage: #{$PROGRAM_NAME} [FILE_NAME] [OWNER] [REPO] [TOKEN]
|
21
|
+
|
22
|
+
Example: #{$PROGRAM_NAME} /path/to/file.json swilliams issue_exporter abcdef
|
23
|
+
|
24
|
+
-h, --help display this help and exit
|
25
|
+
--version display the version
|
26
|
+
|
27
|
+
HERE
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def correct_number_of_args(arg_count)
|
32
|
+
arg_count == 4
|
33
|
+
end
|
34
|
+
|
35
|
+
def process_input(arg, index)
|
36
|
+
case index
|
37
|
+
when 0
|
38
|
+
@json_file = arg
|
39
|
+
when 1
|
40
|
+
@owner = arg
|
41
|
+
when 2
|
42
|
+
@repo = arg
|
43
|
+
when 3
|
44
|
+
@token = arg
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def perform_action
|
49
|
+
importer = TrelloImporter::Importer.new(@json_file, @owner, @repo, @token)
|
50
|
+
importer.import
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
TrelloImporter::Command.new.run
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/lib')
|
2
|
+
|
3
|
+
require 'importer'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'github_trello_importer'
|
7
|
+
s.version = TrelloImporter::VERSION
|
8
|
+
s.required_ruby_version = '>= 2.0'
|
9
|
+
s.summary = 'Tools to import GitHub Issues from Trello'
|
10
|
+
s.description = <<-HERE
|
11
|
+
Take JSON from Trello and create GitHub issues.
|
12
|
+
HERE
|
13
|
+
s.license = 'MIT'
|
14
|
+
s.author = 'Scott Williams'
|
15
|
+
s.email = 'scott.williams@tallwave.com'
|
16
|
+
s.homepage = 'https://github.com/Tallwave/github_trello_importer'
|
17
|
+
s.files = Dir['{bin,lib}/**/*'] + ['github_trello_importer.gemspec']
|
18
|
+
s.executables = ['import-trello']
|
19
|
+
s.extra_rdoc_files = ['LICENSE', 'README.md']
|
20
|
+
s.require_paths = ['lib']
|
21
|
+
end
|
data/lib/importer.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Copyright (c) 2015 Scott Williams
|
2
|
+
|
3
|
+
require "English"
|
4
|
+
require "shellwords"
|
5
|
+
require "json"
|
6
|
+
require "importer/trello_issue_mapper"
|
7
|
+
require "importer/github"
|
8
|
+
require "importer/error_handler"
|
9
|
+
require "importer/import"
|
10
|
+
require "importer/error"
|
11
|
+
require "importer/version"
|
data/lib/importer/cli.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) 2015 Scott Williams
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require "importer"
|
5
|
+
|
6
|
+
module TrelloImporter
|
7
|
+
module CLI
|
8
|
+
|
9
|
+
def run
|
10
|
+
begin
|
11
|
+
OptionParser.new do |opts|
|
12
|
+
define_options opts
|
13
|
+
opts.on "-h", "--help" do
|
14
|
+
puts usage
|
15
|
+
exit
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on "--version" do
|
19
|
+
puts about
|
20
|
+
exit
|
21
|
+
end
|
22
|
+
|
23
|
+
end.parse!
|
24
|
+
rescue OptionParser::ParseError => e
|
25
|
+
raise UsageError, e
|
26
|
+
end
|
27
|
+
|
28
|
+
fail UsageError, "missing argument" if ARGV.empty?
|
29
|
+
fail UsageError, "incorrect number of arguments" unless correct_number_of_args ARGV.count
|
30
|
+
ARGV.each_with_index { |arg, index| process_input arg, index }
|
31
|
+
perform_action()
|
32
|
+
|
33
|
+
rescue UsageError => e
|
34
|
+
puts "#{$PROGRAM_NAME}: #{e}\nTry `#{$PROGRAM_NAME} --help` for more information."
|
35
|
+
exit false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module TrelloImporter
|
2
|
+
class ErrorHandler
|
3
|
+
def response_has_error(response)
|
4
|
+
response.code.to_i > 299
|
5
|
+
end
|
6
|
+
|
7
|
+
def error_message(response_text)
|
8
|
+
response_object = JSON.parse response_text
|
9
|
+
if response_object.is_a? Hash
|
10
|
+
response_object["message"]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def handle_error(error_message, should_abort = true)
|
15
|
+
msg = "ERROR: #{error_message}"
|
16
|
+
if should_abort
|
17
|
+
abort msg
|
18
|
+
else
|
19
|
+
puts msg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "open-uri"
|
2
|
+
|
3
|
+
module TrelloImporter
|
4
|
+
def self.api_url
|
5
|
+
"https://api.github.com/repos/%s/%s/issues?access_token=%s"
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.make_url(owner, repo, token, options = {})
|
9
|
+
url_format = TrelloImporter.api_url
|
10
|
+
root_url = url_format % [owner, repo, token]
|
11
|
+
return root_url unless options[:include_closed_issues] == true
|
12
|
+
root_url + "&state=all"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.make_uri(owner, repo, token, options = {})
|
16
|
+
URI.parse TrelloImporter.make_url(owner, repo, token, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.turn_options_into_querystring(options)
|
20
|
+
querystring = ''
|
21
|
+
options.each do |k, v|
|
22
|
+
escaped_k, escaped_v = URI::encode(k), URI::encode(v)
|
23
|
+
querystring += "#{escaped_k}=#{escaped_v}&"
|
24
|
+
end
|
25
|
+
querystring.chop
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module TrelloImporter
|
5
|
+
class Importer
|
6
|
+
def initialize(json_file, owner, repo, token)
|
7
|
+
@json_file = json_file
|
8
|
+
@owner = owner
|
9
|
+
@repo = repo
|
10
|
+
@token = token
|
11
|
+
end
|
12
|
+
|
13
|
+
def import
|
14
|
+
file_contents = read_file @json_file
|
15
|
+
import_json(file_contents) unless file_contents.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def import_json(json_obj)
|
21
|
+
if json_obj.class == Hash
|
22
|
+
if json_obj["cards"].nil?
|
23
|
+
puts "Could not find 'cards' key"
|
24
|
+
else
|
25
|
+
all_cards = json_obj["cards"]
|
26
|
+
import_json_array all_cards
|
27
|
+
end
|
28
|
+
else
|
29
|
+
puts "Unknown object: #{json_obj.class}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def import_json_array(json_array)
|
34
|
+
json_array.each do |json_hash|
|
35
|
+
import_json_hash json_hash
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def import_json_hash(trello_hash)
|
40
|
+
gh_hash = TrelloImporter::Mapper.map_from_trello trello_hash
|
41
|
+
create_issue(gh_hash)
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_issue(json_obj)
|
45
|
+
uri = TrelloImporter.make_uri @owner, @repo, @token
|
46
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
47
|
+
http.use_ssl = true if uri.scheme == "https"
|
48
|
+
request = Net::HTTP::Post.new uri.request_uri
|
49
|
+
request.content_type = "application/json"
|
50
|
+
request.body = json_obj.to_json
|
51
|
+
handle_response http.request(request)
|
52
|
+
end
|
53
|
+
|
54
|
+
def read_file(filename)
|
55
|
+
path = full_path filename
|
56
|
+
if File.exist? path
|
57
|
+
raw_text = File.read path
|
58
|
+
JSON.parse raw_text
|
59
|
+
else
|
60
|
+
handle_missing_file path
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def full_path(filename)
|
66
|
+
return filename if File.dirname(filename) != "."
|
67
|
+
"#{Dir.pwd}/#{filename}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def handle_response(response)
|
71
|
+
error_handler = ErrorHandler.new
|
72
|
+
if error_handler.response_has_error response
|
73
|
+
error_handler.handle_error error_handler.error_message(response.body), true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def handle_missing_file(filename)
|
78
|
+
puts "Cannot open file: #{filename}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module TrelloImporter
|
2
|
+
class Mapper
|
3
|
+
def self.map_from_trello(trello_hash)
|
4
|
+
body = "#{trello_hash["name"]}<br><br>#{trello_hash["desc"]}<br><br><a href=\"#{trello_hash["url"]}\">View on Trello.</a>"
|
5
|
+
|
6
|
+
{"body" => body, "title" => trello_hash["name"]}
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: github_trello_importer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Scott Williams
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-08 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |2
|
14
|
+
Take JSON from Trello and create GitHub issues.
|
15
|
+
email: scott.williams@tallwave.com
|
16
|
+
executables:
|
17
|
+
- import-trello
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files:
|
20
|
+
- LICENSE
|
21
|
+
- README.md
|
22
|
+
files:
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
- bin/import-trello
|
26
|
+
- github_trello_importer.gemspec
|
27
|
+
- lib/importer.rb
|
28
|
+
- lib/importer/cli.rb
|
29
|
+
- lib/importer/error.rb
|
30
|
+
- lib/importer/error_handler.rb
|
31
|
+
- lib/importer/github.rb
|
32
|
+
- lib/importer/import.rb
|
33
|
+
- lib/importer/trello_issue_mapper.rb
|
34
|
+
- lib/importer/version.rb
|
35
|
+
homepage: https://github.com/Tallwave/github_trello_importer
|
36
|
+
licenses:
|
37
|
+
- MIT
|
38
|
+
metadata: {}
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.0'
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubyforge_project:
|
55
|
+
rubygems_version: 2.2.2
|
56
|
+
signing_key:
|
57
|
+
specification_version: 4
|
58
|
+
summary: Tools to import GitHub Issues from Trello
|
59
|
+
test_files: []
|