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 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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env rake
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Dir[File.expand_path "../lib/tasks/*.rake", __FILE__].each do |file|
5
+ load file
6
+ end
data/bin/rdv ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.push File.expand_path("../../lib", __FILE__)
4
+
5
+ require "rdv"
6
+
7
+ Rdv::CLI.start(ARGV)
8
+
data/lib/rdv.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Rdv
2
+ end
3
+
4
+ require "rdv/parser"
5
+ require "rdv/issues"
6
+ require "rdv/cli"
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
@@ -0,0 +1,17 @@
1
+ class String
2
+ def colorize(color_code)
3
+ "\e[#{color_code}m#{self}\e[0m"
4
+ end
5
+
6
+ def red
7
+ colorize(31)
8
+ end
9
+
10
+ def green
11
+ colorize(32)
12
+ end
13
+
14
+ def yellow
15
+ colorize(33)
16
+ end
17
+ 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,8 @@
1
+ module Rdv
2
+ module Object
3
+ end
4
+ end
5
+
6
+ require "rdv/object/base"
7
+ require "rdv/object/block"
8
+ require "rdv/object/item"
@@ -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
@@ -0,0 +1,3 @@
1
+ module Rdv
2
+ VERSION = "0.0.1"
3
+ end
@@ -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: []