kanboard 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: deb5937ebfd90e9c95f7068512deb0b27747f5af
4
+ data.tar.gz: 08be304d8eaa9b1e8157ff5ee1409d8b79c71001
5
+ SHA512:
6
+ metadata.gz: 23280c79d9fef6356e82bf571be4d8dbb9fc0c12acae97a577bd74a49328e3c6806071ddeec00a6985a4a11ef9b7313840fc3463e5c772ad64ed57391755aedd
7
+ data.tar.gz: 1debdd2e0e2fb611131de93160c4bd650adf2bcc336eb7b5fbdc52b9b66b0aefc68d2885ebbb78503993718786c3e4a2bdea6bdf30d88a7db9141935af1c1ea0
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ /nbproject/private/
19
+ .DS_Store
20
+ _site
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kanboard.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Adolfo Villafiorita
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Kanboard
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'kanboard'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install kanboard
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/kanboard ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'kanboard'
4
+
5
+ ARGV.each do |filename|
6
+ Kanboard::do_it(filename)
7
+ end
8
+
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>KanBoard - a Kanban Board from a Textile File</title>
5
+
6
+ <link href="{{site.url}}/stylesheets/default.css" media="screen" rel="stylesheet" type="text/css" />
7
+ </head>
8
+ <body>
9
+ {{ content }}
10
+ </body>
11
+ </html>
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: Project 1
3
+ layout: default
4
+ ---
5
+ h1. Project 1
6
+
7
+ All text inserted (and not starting with a dash or with a "hN" directive) will be ignored.
8
+
9
+ The following items will be used by the script and used to generated a Kanban Board.
10
+
11
+ The kanboard is accessible from:
12
+
13
+ * "kanboard/Project 1.html":kanboard/Project_1.html
14
+ * "kanboard/Project 1.html":kanboard/Project_1-assignments.html
15
+
16
+ h2. Inbox
17
+
18
+ - action I1 +bug #important
19
+ - action I2 +feature
20
+ - action I3 +bug
21
+
22
+ h2. Approved
23
+
24
+ - action A1 +feature @adolfo
25
+ - action A2 +bug @andrea
26
+ - action A3 @pietro
27
+
28
+ h2. In Progress
29
+
30
+ - action D1 +feature @adolfo
31
+ - action D2 +bug @pietro
32
+ - action D3
33
+
34
+ h2. Done
35
+
36
+ h2. Trashed
@@ -0,0 +1,11 @@
1
+ table {
2
+ border: 1px solid #ccc;
3
+ width: 100%
4
+ }
5
+
6
+ .card {
7
+ border: 1px solid #ccc;
8
+ margin: 2px;
9
+ padding: 3px;
10
+ background: #eee;
11
+ }
data/kanboard.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kanboard/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "kanboard"
8
+ spec.version = Kanboard::VERSION
9
+ spec.authors = ["Adolfo Villafiorita"]
10
+ spec.email = ["adolfo.villafiorita@icloud.com"]
11
+ spec.description = %q{Generate a kanboard from a textile file}
12
+ spec.summary = %q{Generate a kanboard from a textile file}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
data/lib/kanboard.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'kanboard/version'
2
+ require 'kanboard/board'
3
+ require 'kanboard/jekyll_renderer'
4
+
5
+ module Kanboard
6
+
7
+ def self.do_it(filename)
8
+ board = Board.new
9
+ board.load(filename)
10
+
11
+ r = JekyllRenderer.new(board)
12
+ r.render
13
+ end
14
+ end
@@ -0,0 +1,95 @@
1
+ # make a textile file into a kanban board
2
+ #
3
+ # input a file in the form specified by example.textile
4
+ # result: an internal representation of the board good for being displayed, which
5
+ # includes:
6
+ #
7
+ # - project name
8
+ # - list of workflow states defined in the file
9
+ # - list of swimlanes defined in the files
10
+ # - entries defined in the file organized in a two-dimensional matrix:
11
+ #
12
+ # (status, swimlane)
13
+ #
14
+ # (so that they can be placed in the kanban board)
15
+ #
16
+ # the entries are stored with a hash of arrays. (status, swimlane) are transformed
17
+ # into a unique key (with string concatenation) and the entry added as elements
18
+ # of an array
19
+
20
+ require "kanboard/card"
21
+
22
+ class Kanboard::Board
23
+ attr_accessor :project, :statuses, :swimlanes, :all_cards
24
+
25
+ def initialize
26
+ @project = ""
27
+ @statuses = [] # all statuses (h2. strings) defined in the input file
28
+ @swimlanes = [] # all unique swim-lane (+ strings) defined in the input file
29
+ @cards = Hash.new # cards organised by board position
30
+ @all_cards = Array.new # all cards defined in the input file
31
+ end
32
+
33
+ def load filename
34
+ current_status = "" # current status
35
+
36
+ File.open(filename).each do |line|
37
+ # set the title to the first h1 found in the file
38
+ match = line.match(/^h1\.[ ]+(.+)$/)
39
+ if match and @project == ""
40
+ @project = match[1]
41
+ end
42
+
43
+ # look for statuses and add them to the list of statuses.
44
+ # don't bother about duplications
45
+ match = line.match(/^h2\.[ ]+(.+)$/)
46
+ if match
47
+ @statuses << match[1]
48
+ current_status = match[1]
49
+ end
50
+
51
+ # look for cards and manage them
52
+ if line.start_with?('- ') # make sure we ignore YAML front matter ("---")
53
+ card = Kanboard::Card.new(@project, @status, line)
54
+ swimlane = card.swimlane
55
+ owner = card.owner
56
+
57
+ @swimlanes << swimlane unless @swimlanes.include? swimlane
58
+
59
+ position = hash(current_status, swimlane)
60
+ @cards[position] = Array.new unless @cards[position]
61
+ @cards[position] << card
62
+
63
+ @all_cards << card
64
+ end
65
+ end
66
+ end
67
+
68
+ def cards(status, swimlane)
69
+ @cards[hash(status, swimlane)] || Array.new # so that we always return an array
70
+ end
71
+
72
+ #
73
+ # return all the owners mentioned in the input file
74
+ #
75
+ def owners
76
+ @all_cards.map { |c| c.owner }.uniq
77
+ end
78
+
79
+ #
80
+ # return all the cards owned by owner
81
+ #
82
+ def cards_of(owner)
83
+ @all_cards.select { |c| c.owner == owner }
84
+ end
85
+
86
+ private
87
+
88
+ #
89
+ # generate an hash which uniquely identifies a cell in the kanban board
90
+ #
91
+ def hash(status, swimlane)
92
+ status + "*" + swimlane
93
+ end
94
+
95
+ end
@@ -0,0 +1,74 @@
1
+ # Kanban card
2
+ #
3
+ # Textile markupped text describing a card.
4
+ # a card is a line of text starting with a dash "-"
5
+ #
6
+ # - @adolfo fix this #bug: 234 (c:2013-02-15)
7
+ #
8
+ # the card embeds information such as:
9
+ #
10
+ # * owner: @name
11
+ # * swimlane: +swimlane (at most one)
12
+ # * tags: #tag1, #tag2 (TODO)
13
+ #
14
+ # * creation date: c:
15
+ # * finish date: f:
16
+ # * due date: d:
17
+ #
18
+ # the card stores also information which is defined elsewhere in the kanban file.
19
+ # This information includes:
20
+ #
21
+ # - project: the project the card refers to (set with a h1. tag in the file)
22
+ # - status: the current status of the card (set with a h2. tag in the file)
23
+ #
24
+
25
+ class Kanboard::Card
26
+ GENERIC_SWIMLANE = "Generic" # the swimlane for cards with no swimlane
27
+ NO_ONE = "Unassigned" # the owned of cards not owned by anyone
28
+
29
+ attr_accessor :project, :status
30
+
31
+ def initialize(project, status, title)
32
+ @project = project
33
+ @status = status
34
+ @title = title[2, title.length] # forget about the initial "- "
35
+ end
36
+
37
+ def owner
38
+ find("@", @title) || NO_ONE
39
+ end
40
+
41
+ def swimlane
42
+ find("\\+", @title) || GENERIC_SWIMLANE
43
+ end
44
+
45
+ def created
46
+ find("c:", @title)
47
+ end
48
+
49
+ def finished
50
+ find("f:", @title)
51
+ end
52
+
53
+ def done?
54
+ finished != nil
55
+ end
56
+
57
+ def due
58
+ find("d:", @title)
59
+ end
60
+
61
+ def to_s
62
+ @title
63
+ end
64
+
65
+ private
66
+
67
+ # find a substring of the type tag[\w]+ in argument
68
+ # return nil if not found.
69
+ def find(tag, string)
70
+ match = string.match(Regexp.new(tag + "([\\w]+)"))
71
+ match ? match[1] : nil
72
+ end
73
+
74
+ end
@@ -0,0 +1,80 @@
1
+ require 'kanboard/board'
2
+
3
+ class Kanboard::JekyllRenderer
4
+ OUTPUT_DIR = "kanboard"
5
+
6
+ def initialize(board)
7
+ @board = board
8
+ end
9
+
10
+ def render
11
+ Dir.mkdir(OUTPUT_DIR) if not Dir.exists?(OUTPUT_DIR)
12
+
13
+ board_filename = File.join(OUTPUT_DIR,
14
+ @board.project.gsub(/[\p{Punct}\p{Space}]+/, "_") +
15
+ ".textile")
16
+ File.open(board_filename, 'w') do |f|
17
+ f.puts render_board
18
+ end
19
+
20
+ board_filename = File.join(OUTPUT_DIR,
21
+ @board.project.gsub(/[\p{Punct}\p{Space}]+/, "_") +
22
+ "-assignments.textile")
23
+ File.open(board_filename, 'w') do |f|
24
+ f.puts render_assignments
25
+ end
26
+ end
27
+
28
+ def render_board
29
+ statuses = @board.statuses
30
+ swimlanes = @board.swimlanes
31
+
32
+ output = ""
33
+ output << "---
34
+ title: Kanban Board for #{@board.project}
35
+ layout: default
36
+ ---
37
+ h1. Board for #{@board.project}\n\n"
38
+ output << "<table class=\"board\">"
39
+ output << "<tr>\n"
40
+ output << " <th></th>\n"
41
+ statuses.each do |status|
42
+ output << " <th>#{status}</th>\n"
43
+ end
44
+ output << "</tr>\n"
45
+
46
+ swimlanes.each do |swimlane|
47
+ output << "<tr>\n"
48
+ output << " <td>#{swimlane}</td>\n"
49
+
50
+ statuses.each do |status|
51
+ output << " <td>\n"
52
+ @board.cards(status, swimlane).each do |card|
53
+ output << " <div class=\"card\">#{card}</div>\n"
54
+ end
55
+ output << " </td>\n"
56
+ end
57
+ output << "</tr>\n"
58
+ end
59
+ output << "</table>\n"
60
+
61
+ output
62
+ end
63
+
64
+ def render_assignments
65
+ output = ""
66
+ output << "---
67
+ title: Assignments for #{@board.project}
68
+ layout: default
69
+ ---
70
+ h1. Assignments for #{@board.project}\n\n"
71
+ @board.owners.each do |owner|
72
+ output << "h2. #{owner}\n"
73
+ @board.cards_of(owner).each do |card|
74
+ output << "* #{card}\n"
75
+ end
76
+ end
77
+ output
78
+ end
79
+
80
+ end
@@ -0,0 +1,3 @@
1
+ module Kanboard
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kanboard
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Adolfo Villafiorita
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Generate a kanboard from a textile file
42
+ email:
43
+ - adolfo.villafiorita@icloud.com
44
+ executables:
45
+ - kanboard
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bin/kanboard
55
+ - example/_layouts/default.html
56
+ - example/project1.textile
57
+ - example/stylesheets/default.css
58
+ - kanboard.gemspec
59
+ - lib/kanboard.rb
60
+ - lib/kanboard/board.rb
61
+ - lib/kanboard/card.rb
62
+ - lib/kanboard/jekyll_renderer.rb
63
+ - lib/kanboard/version.rb
64
+ homepage: ''
65
+ licenses:
66
+ - MIT
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubyforge_project:
84
+ rubygems_version: 2.0.3
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: Generate a kanboard from a textile file
88
+ test_files: []
89
+ has_rdoc: