rdv 0.0.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +52 -0
- data/Rakefile +6 -0
- data/bin/rdv +8 -0
- data/lib/rdv.rb +6 -0
- data/lib/rdv/cli.rb +38 -0
- data/lib/rdv/core_ext/string.rb +17 -0
- data/lib/rdv/issues.rb +70 -0
- data/lib/rdv/object.rb +8 -0
- data/lib/rdv/object/base.rb +17 -0
- data/lib/rdv/object/block.rb +34 -0
- data/lib/rdv/object/item.rb +44 -0
- data/lib/rdv/parser.rb +30 -0
- data/lib/rdv/version.rb +3 -0
- data/lib/tasks/rdv_tasks.rake +17 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f99ec689d6fad21107ce3b252787078d8075058f
|
4
|
+
data.tar.gz: c800d18457a91002a60a270d21960f619d5ee1bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 57abc88789c223c13fa25dc6c9f83ca3826df2159af19c683907f2089c9fe7352bd5328d3cc43a952a88ff9e921de9077069a8c2c9dbacb15a133ec93a2b4e1a
|
7
|
+
data.tar.gz: c16155fa70434704f23dd084dcf569b539abaa982af679e4839d546ea875aa676f42013a3a4ae7c817e434d73291536dfb7b17e4f1880d626f55f92299635383
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Valentin Ballestrino
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Rdv
|
2
|
+
|
3
|
+
Write plain text and export to Github issues without too much overhead.
|
4
|
+
|
5
|
+
## Converter usage
|
6
|
+
|
7
|
+
Install the gem :
|
8
|
+
|
9
|
+
```bash
|
10
|
+
gem install rdv
|
11
|
+
```
|
12
|
+
|
13
|
+
Then use the provided executable to convert your `.rdv` file :
|
14
|
+
|
15
|
+
```bash
|
16
|
+
# Syntax : rdv convert <repo> <file_path>
|
17
|
+
rdv convert vala/rdv my_file.rdv
|
18
|
+
```
|
19
|
+
|
20
|
+
## Markup
|
21
|
+
|
22
|
+
The file structure needed to be converted is the following :
|
23
|
+
|
24
|
+
```text
|
25
|
+
Newsletter :
|
26
|
+
- Design newsletter template @vala :
|
27
|
+
* Do this
|
28
|
+
* Do that
|
29
|
+
* etc.
|
30
|
+
- Other issue with labels
|
31
|
+
Do something not being in a list ...
|
32
|
+
blah...
|
33
|
+
tags | at | the | end
|
34
|
+
|
35
|
+
Other Theme :
|
36
|
+
-> Issue with a preceding arrow
|
37
|
+
Issue content, can be anything ...
|
38
|
+
tag it | here
|
39
|
+
```
|
40
|
+
|
41
|
+
What matters :
|
42
|
+
* Structure depends on indentation, so Theme / Issue / Content should be respected
|
43
|
+
* Collaborator assignment should be at the end of the issue title
|
44
|
+
* Labels should be at the end of the issue content, separated by pipes (|)
|
45
|
+
|
46
|
+
What is optional :
|
47
|
+
* Collaborator assignment is optional
|
48
|
+
* Tags are optional
|
49
|
+
* Dashes or arrows at the beginning of the Theme or the Issue title will be stripped
|
50
|
+
* Colon at the end of Theme or Issue title will be stripped
|
51
|
+
* Issue content can contain any Github Issue supported markup
|
52
|
+
|
data/Rakefile
ADDED
data/bin/rdv
ADDED
data/lib/rdv.rb
ADDED
data/lib/rdv/cli.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "io/console"
|
3
|
+
require "rdv/core_ext/string"
|
4
|
+
require "octokit"
|
5
|
+
|
6
|
+
module Rdv
|
7
|
+
class CLI < Thor
|
8
|
+
desc "convert REPOSITORY FILE", "Converts a .rdv file to Github issues"
|
9
|
+
def convert repo, file
|
10
|
+
puts "Converting file : #{ file } to issues in #{ repo }".yellow
|
11
|
+
repo = repo
|
12
|
+
# Parse themes and issues from input file
|
13
|
+
themes = Parser.parse File.read(file)
|
14
|
+
# Request user's Github credentials to connect to API and build client
|
15
|
+
client = build_github_client
|
16
|
+
# Convert themes to issues and count them
|
17
|
+
issues = Issues.create_from(client, repo, themes)
|
18
|
+
puts "Created #{ issues.length } issues".yellow
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def build_github_client
|
24
|
+
puts "Please enter your Github credentials.".green
|
25
|
+
print "Username : ".green
|
26
|
+
username = STDIN.gets.chop
|
27
|
+
print "Password : ".green
|
28
|
+
password = STDIN.noecho(&:gets).chop
|
29
|
+
puts ""
|
30
|
+
|
31
|
+
Octokit::Client.new(login: username, password: password)
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_issues themes
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/rdv/issues.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
module Rdv
|
2
|
+
class Issues
|
3
|
+
attr_accessor :client, :repo
|
4
|
+
|
5
|
+
def initialize client, repo
|
6
|
+
self.client = client
|
7
|
+
self.repo = repo
|
8
|
+
end
|
9
|
+
|
10
|
+
# Creates issues from the current themes
|
11
|
+
def create_issues themes
|
12
|
+
issues = themes.reduce([]) do |issues, theme|
|
13
|
+
main_label = theme.name
|
14
|
+
issues + theme.list.map do |issue|
|
15
|
+
# Add theme as the first issue's tag
|
16
|
+
issue.tags.unshift(main_label)
|
17
|
+
# Create issue
|
18
|
+
create_issue(issue)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
issues.compact
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_issue issue
|
26
|
+
# Serialize the issue to compare it to existing ones
|
27
|
+
serialized = serialize_issue(issue.name, issue.tags)
|
28
|
+
# If issue already exist, don't create it
|
29
|
+
if (existing = existing_issues[serialized])
|
30
|
+
puts ("Issue \"#{ issue.name }\" not created, already exists " +
|
31
|
+
"as ##{ existing.number } / #{ existing.html_url }").red
|
32
|
+
return
|
33
|
+
end
|
34
|
+
# Create issue in repo
|
35
|
+
client.create_issue(repo, issue.name, issue.content, {
|
36
|
+
labels: issue.tags, assignee: issue.user
|
37
|
+
})
|
38
|
+
rescue Octokit::UnprocessableEntity => e
|
39
|
+
data = e.response_body
|
40
|
+
# Tell that issue couldn't be created
|
41
|
+
puts "Couldn't create issue \"#{ issue.name }\", #{ data.message }.".red
|
42
|
+
# Display each field with errors
|
43
|
+
data.errors.each do |error|
|
44
|
+
puts "- #{ error.code } #{ error.field } #{ error.value }".red
|
45
|
+
end
|
46
|
+
# Ensure nil is returned so compacting issues array will remove it
|
47
|
+
# from created ones
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
# Retrieves all existing issues for the current repo and stores them
|
52
|
+
# in a hash with the key being some kind of unique identifier
|
53
|
+
#
|
54
|
+
def existing_issues
|
55
|
+
@existing_issues ||=
|
56
|
+
client.list_issues(repo).reduce({}) do |hash, issue|
|
57
|
+
hash[serialize_issue(issue.title, issue.labels.map(&:name))] = issue
|
58
|
+
hash
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def serialize_issue title, labels
|
63
|
+
"#{ title }-#{ labels.sort.join(":") }"
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.create_from client, repo, themes
|
67
|
+
new(client, repo).create_issues(themes)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/rdv/object.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module Rdv
|
2
|
+
module Object
|
3
|
+
class Base
|
4
|
+
def clean str
|
5
|
+
str.gsub(/^\->?\s+/, "").gsub(/(\s*\:)??$/, "").strip
|
6
|
+
end
|
7
|
+
|
8
|
+
def capitalize str
|
9
|
+
str.strip.split(" ").map(&:capitalize).join(" ")
|
10
|
+
end
|
11
|
+
|
12
|
+
def trim_indentation str
|
13
|
+
str.gsub(/^\s{2}/, "")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rdv
|
2
|
+
module Object
|
3
|
+
class Block < Base
|
4
|
+
attr_accessor :name, :list, :raw_list
|
5
|
+
|
6
|
+
def initialize header
|
7
|
+
@name = capitalize(header)
|
8
|
+
@raw_list = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_line(line)
|
12
|
+
@raw_list << line
|
13
|
+
end
|
14
|
+
|
15
|
+
def build
|
16
|
+
@list = @raw_list.reduce([]) do |list, line|
|
17
|
+
line = trim_indentation(line)
|
18
|
+
|
19
|
+
if line.match(/^[^\s]+/)
|
20
|
+
list << Item.new(line)
|
21
|
+
elsif list.length > 0 && line.length > 0
|
22
|
+
list.last.add_line(line)
|
23
|
+
end
|
24
|
+
|
25
|
+
list
|
26
|
+
end
|
27
|
+
|
28
|
+
@list.each(&:build)
|
29
|
+
|
30
|
+
@name = clean(@name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Rdv
|
2
|
+
module Object
|
3
|
+
class Item < Base
|
4
|
+
attr_accessor :name, :content, :raw_content, :user, :tags
|
5
|
+
|
6
|
+
def initialize name
|
7
|
+
@name = name
|
8
|
+
@raw_content = []
|
9
|
+
@tags = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_line line
|
13
|
+
@raw_content << line
|
14
|
+
end
|
15
|
+
|
16
|
+
def build
|
17
|
+
# Clean name and store it back
|
18
|
+
@name = clean(@name.strip)
|
19
|
+
# Fetch contents
|
20
|
+
contents = @raw_content.reduce([]) do |list, line|
|
21
|
+
line = trim_indentation(line)
|
22
|
+
list << line unless line.match(/^\s+$/)
|
23
|
+
list
|
24
|
+
end.compact
|
25
|
+
|
26
|
+
if contents.last.scan(/\|/).length > 0
|
27
|
+
@tags = contents.pop.split("|").map do |tag|
|
28
|
+
capitalize(tag)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
@content = contents.join("")
|
33
|
+
|
34
|
+
# If a @user tag is found in the issue name, strip it and store it as
|
35
|
+
# the assignee user login
|
36
|
+
if (user = @name.match(/@(\w+)$/))
|
37
|
+
@user = user[1]
|
38
|
+
# Clean username from item name
|
39
|
+
@name = @name.gsub(/@(\w+)$/, "").strip
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/rdv/parser.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "rdv/object"
|
2
|
+
|
3
|
+
module Rdv
|
4
|
+
class Parser
|
5
|
+
def self.parse data
|
6
|
+
(@parser ||= self.new).parse(data)
|
7
|
+
end
|
8
|
+
|
9
|
+
def parse data
|
10
|
+
blocks = find_blocks(data)
|
11
|
+
blocks.each(&:build)
|
12
|
+
blocks
|
13
|
+
end
|
14
|
+
|
15
|
+
def find_blocks text
|
16
|
+
text.each_line.reduce([]) do |blocks, line|
|
17
|
+
# If line starts with no tab but has content, we start a new block
|
18
|
+
if line.match(/^[^\s]+/)
|
19
|
+
blocks << Object::Block.new(line)
|
20
|
+
# If we have a content line that starts with one or more tabs, we feed
|
21
|
+
# last existing block, if we already have one
|
22
|
+
elsif line.length > 0 && blocks.length > 0
|
23
|
+
blocks.last.add_line(line)
|
24
|
+
end
|
25
|
+
|
26
|
+
blocks
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/rdv/version.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rdv"
|
2
|
+
|
3
|
+
namespace :rdv do
|
4
|
+
task :example do
|
5
|
+
filepath = File.expand_path "../../../samples/example.rdv", __FILE__
|
6
|
+
parsed = Rdv::Parser.parse(File.read(filepath))
|
7
|
+
end
|
8
|
+
|
9
|
+
task :parse do
|
10
|
+
contents = File.read ENV['FILE']
|
11
|
+
blocks = Rdv::Parser.parse(contents)
|
12
|
+
|
13
|
+
blocks.each do |block|
|
14
|
+
puts block.inspect
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rdv
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Valentin Ballestrino
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-07-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
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'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: octokit
|
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'
|
41
|
+
description: rdv converts plain text markup into github issues and post them to the
|
42
|
+
desired repository
|
43
|
+
email:
|
44
|
+
- vala@glyph.fr
|
45
|
+
executables:
|
46
|
+
- rdv
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- bin/rdv
|
51
|
+
- lib/rdv/cli.rb
|
52
|
+
- lib/rdv/core_ext/string.rb
|
53
|
+
- lib/rdv/issues.rb
|
54
|
+
- lib/rdv/object/base.rb
|
55
|
+
- lib/rdv/object/block.rb
|
56
|
+
- lib/rdv/object/item.rb
|
57
|
+
- lib/rdv/object.rb
|
58
|
+
- lib/rdv/parser.rb
|
59
|
+
- lib/rdv/version.rb
|
60
|
+
- lib/rdv.rb
|
61
|
+
- lib/tasks/rdv_tasks.rake
|
62
|
+
- MIT-LICENSE
|
63
|
+
- Rakefile
|
64
|
+
- README.md
|
65
|
+
homepage: http://www.glyph.fr
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.0.3
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: Small DSL to write issues in plain text
|
89
|
+
test_files: []
|