whatToDo 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +19 -0
- data/LICENSE +20 -0
- data/README.md +49 -0
- data/Rakefile +1 -0
- data/bin/whatToDo +3 -0
- data/lib/whatToDo.rb +66 -0
- data/lib/whatToDo/check/bootstrap.rb +7 -0
- data/lib/whatToDo/check/readme.rb +17 -0
- data/lib/whatToDo/check/todo.rb +104 -0
- data/lib/whatToDo/check_manager.rb +37 -0
- data/lib/whatToDo/facet/git.rb +3 -0
- data/lib/whatToDo/facet/ruby.rb +3 -0
- data/lib/whatToDo/facet_analyzer.rb +24 -0
- data/lib/whatToDo/util.rb +11 -0
- data/lib/whatToDo/version.rb +3 -0
- data/screenshot.png +0 -0
- data/whatToDo.gemspec +28 -0
- metadata +117 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Benjamin Kammerl aka phortx
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
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, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# WhatToDo
|
2
|
+
|
3
|
+
As a developer you probably know that situation: You've been hacking in a project for some weeks and suddenly you're stuck or don't have any time to complete or have to stop developing for some other reason. The project stays untouched in the git repository and is idling. Dome weeks or months or even years later you want to get back in the project and finish it or fix a bug or somethine like that. But you don't know were the fuck you have quit the work in the project and have no idea what to do next.
|
4
|
+
|
5
|
+
The same issue occurs if you're joining a new project or want to start to contribute to an OpenSource project. You have no idea where to start.
|
6
|
+
|
7
|
+
WhatToDo is a tool which aims to help you over that obstacle, by analysing your project and telling you what you can do. It gives you concrete todos to help you to get startet with the project and get back into it.
|
8
|
+
|
9
|
+
Works for ruby projects only currently.
|
10
|
+
|
11
|
+
![screenshot](https://raw.github.com/phortx/WhatToDo/master/screenshot.png)
|
12
|
+
|
13
|
+
|
14
|
+
(And this gem is under heavy development currently. Contributions are welcome.)
|
15
|
+
|
16
|
+
|
17
|
+
# Dependencies
|
18
|
+
You just need at least ruby 1.9.3 installed.
|
19
|
+
|
20
|
+
|
21
|
+
# Installation
|
22
|
+
gem install WhatToDo
|
23
|
+
|
24
|
+
|
25
|
+
# Usage
|
26
|
+
Just run <code>whatToDo</code> in your project root.
|
27
|
+
|
28
|
+
|
29
|
+
# License
|
30
|
+
The MIT License (MIT)
|
31
|
+
|
32
|
+
Copyright (c) 2013 Benjamin Kammerl aka phortx
|
33
|
+
|
34
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
35
|
+
this software and associated documentation files (the "Software"), to deal in
|
36
|
+
the Software without restriction, including without limitation the rights to
|
37
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
38
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
39
|
+
subject to the following conditions:
|
40
|
+
|
41
|
+
The above copyright notice and this permission notice shall be included in all
|
42
|
+
copies or substantial portions of the Software.
|
43
|
+
|
44
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
45
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
46
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
47
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
48
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
49
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/whatToDo
ADDED
data/lib/whatToDo.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'optparse'
|
3
|
+
require 'colored'
|
4
|
+
require 'whatToDo/util'
|
5
|
+
require 'whatToDo/check_manager'
|
6
|
+
require 'whatToDo/facet_analyzer'
|
7
|
+
|
8
|
+
|
9
|
+
# Command line options
|
10
|
+
options = {
|
11
|
+
debug: true,
|
12
|
+
}
|
13
|
+
|
14
|
+
opt_parser = OptionParser.new do |opt|
|
15
|
+
opt.banner = 'Usage: whatToDo [OPTIONS]'
|
16
|
+
opt.separator ''
|
17
|
+
opt.separator 'Options'
|
18
|
+
|
19
|
+
opt.on('-d', '--debug', 'Enable stacktrace output.') do
|
20
|
+
options[:debug] = true
|
21
|
+
end
|
22
|
+
|
23
|
+
opt.on('-h', '--help', 'help') do
|
24
|
+
puts opt_parser
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
opt_parser.parse!
|
29
|
+
|
30
|
+
|
31
|
+
# Init the facet analyser and run it so we know what project we have here.
|
32
|
+
facet_analyzer = WhatToDo::FacetAnalyzer.new
|
33
|
+
facets = facet_analyzer.facets
|
34
|
+
|
35
|
+
|
36
|
+
# Init the check manager and run all checks
|
37
|
+
check_manager = WhatToDo::CheckManager.new(facets)
|
38
|
+
check_results = check_manager.run_checks(10)
|
39
|
+
|
40
|
+
|
41
|
+
# Show the facets
|
42
|
+
puts
|
43
|
+
puts 'Project facets: '.bold.white
|
44
|
+
puts ' ' + facets.map{ |f| f.to_s }.join(', ')
|
45
|
+
puts
|
46
|
+
|
47
|
+
|
48
|
+
# If it's a git project, display the last commit messages and the last changed files
|
49
|
+
if facets.include?(:git)
|
50
|
+
puts 'Last commits:'.bold.white
|
51
|
+
puts indent(`git log -5 --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative`, 2)
|
52
|
+
puts
|
53
|
+
|
54
|
+
puts 'Last changed files:'.bold.white
|
55
|
+
puts indent(`git diff $(git log -5 --format=%H | tail -n1).. --stat`, 1)
|
56
|
+
puts
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# Print the result
|
61
|
+
if check_results.length > 0
|
62
|
+
puts 'Suggested todo:'.bold.white
|
63
|
+
puts ' ' + check_results.sample
|
64
|
+
else
|
65
|
+
puts 'Nothing to do here!'.green
|
66
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
check do
|
2
|
+
re = nil
|
3
|
+
found = false
|
4
|
+
|
5
|
+
['README', 'README.md', 'README.txt', 'README.html'].each do |fileName|
|
6
|
+
if File.file?(fileName)
|
7
|
+
found = true
|
8
|
+
break
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
unless found
|
13
|
+
re = "There is no readme file in that project. Create one!"
|
14
|
+
end
|
15
|
+
|
16
|
+
re
|
17
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
##
|
2
|
+
## Executes a recursive grep in the current directory to find all todos,
|
3
|
+
## and the respecitve filename and linenumber. If there's a .gitignore
|
4
|
+
## that function will ignore all directories and files from .gitignore
|
5
|
+
##
|
6
|
+
|
7
|
+
def get_lines
|
8
|
+
exclude = ''
|
9
|
+
|
10
|
+
if File.file?(".gitignore")
|
11
|
+
exclude = `cat .gitignore`.split("\n").map { |l| " | grep -v '^#{l}'" }
|
12
|
+
exclude = exclude.join
|
13
|
+
end
|
14
|
+
|
15
|
+
`egrep -rnH 'TODO|FIXME|XXX' * | grep -v '^Binary file' #{exclude}`.split("\n")
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
##
|
21
|
+
## Builds a code sample from the given file and linenumber. Will display
|
22
|
+
## the 4 lines above and below the relevant line and will highlight the
|
23
|
+
## relevant line.
|
24
|
+
##
|
25
|
+
|
26
|
+
def code_sample(file, line)
|
27
|
+
line = line.to_i
|
28
|
+
|
29
|
+
from = line - 4
|
30
|
+
from = 0 if from < 0
|
31
|
+
|
32
|
+
result = "\n\n"
|
33
|
+
|
34
|
+
snippet(file, from, line + 4).split("\n").each do |code_line|
|
35
|
+
active = (line == from)
|
36
|
+
spaces = " " * (8 - from.to_s.length - (active ? 3 : 0))
|
37
|
+
result << spaces + (active ? '>> '.bold.red : '')
|
38
|
+
result << from.to_s.bold.yellow + ": ".bold.yellow
|
39
|
+
|
40
|
+
first = true
|
41
|
+
|
42
|
+
if code_line.length > 0
|
43
|
+
scan = code_line.scan(/^ +/)[0]
|
44
|
+
ident = scan ? scan.length + 12 : 12
|
45
|
+
code_line.scan(/.{1,80}/m).each do |l|
|
46
|
+
result << (first ? '' : ' ' * ident) + (active ? l.bold.red : l) + "\n"
|
47
|
+
first = false
|
48
|
+
end
|
49
|
+
else
|
50
|
+
result << "\n"
|
51
|
+
end
|
52
|
+
|
53
|
+
from += 1
|
54
|
+
end
|
55
|
+
|
56
|
+
result
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
##
|
62
|
+
## Extracs a code snippet from a file and reduced the identation to the minimum
|
63
|
+
##
|
64
|
+
|
65
|
+
def snippet(file, from, to)
|
66
|
+
code = ""
|
67
|
+
current_line = 0
|
68
|
+
|
69
|
+
File.open(file, 'r') do |f|
|
70
|
+
while read_line = f.gets
|
71
|
+
current_line += 1
|
72
|
+
code << read_line.gsub(/\t/m, ' ') if current_line >= from && current_line <= to
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
code.gsub(/^#{code.scan(/^ +/).min}/, '')
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
##
|
82
|
+
## Reduces the identation of a given string to the minimum
|
83
|
+
##
|
84
|
+
|
85
|
+
def unindent(code)
|
86
|
+
code.gsub(/^#{scan(/^\s+/).min}/, "")
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
##
|
92
|
+
## Register the check script
|
93
|
+
##
|
94
|
+
|
95
|
+
check do
|
96
|
+
todos = get_lines.map do |line|
|
97
|
+
splitted = line.split(':', 3)
|
98
|
+
result = "Found a ToDo in #{splitted[0]} at line #{splitted[1]}:\n"
|
99
|
+
result << code_sample(splitted[0], splitted[1])
|
100
|
+
result
|
101
|
+
end
|
102
|
+
|
103
|
+
todos.sample
|
104
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module WhatToDo
|
4
|
+
class CheckManager
|
5
|
+
def initialize(facets = [])
|
6
|
+
@checks = []
|
7
|
+
@facets = facets
|
8
|
+
|
9
|
+
# Require all check scripts
|
10
|
+
dir = Pathname.new(File.dirname(__FILE__) + '/check').cleanpath
|
11
|
+
Dir["#{dir}/*.rb"].each do |file|
|
12
|
+
instance_eval(File.open(File.expand_path(file)).read)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def check(facets = [], &block)
|
17
|
+
if !facets.any? || (facets & @facets).any?
|
18
|
+
@checks << block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def run_checks(count)
|
23
|
+
results = []
|
24
|
+
|
25
|
+
@checks.each do |check|
|
26
|
+
result = instance_eval(&check)
|
27
|
+
|
28
|
+
unless result == nil || result == false
|
29
|
+
results << result
|
30
|
+
break if results.length >= count
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
results
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WhatToDo
|
2
|
+
class FacetAnalyzer
|
3
|
+
attr_reader :facets
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@facets = []
|
7
|
+
|
8
|
+
# Require all facet scripts
|
9
|
+
dir = Pathname.new(File.dirname(__FILE__) + '/facet').cleanpath
|
10
|
+
Dir["#{dir}/*.rb"].each do |file|
|
11
|
+
instance_eval(File.open(File.expand_path(file)).read)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def facet(facets)
|
16
|
+
unless facets.is_a?(Array)
|
17
|
+
facets = [facets]
|
18
|
+
end
|
19
|
+
|
20
|
+
@facets += facets if yield
|
21
|
+
@facets.flatten
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/screenshot.png
ADDED
Binary file
|
data/whatToDo.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift(lib) unless $:.include?(lib)
|
4
|
+
require 'whatToDo/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'whatToDo'
|
8
|
+
s.version = WhatToDo::VERSION.to_s
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ['Benjamin Kammerl']
|
11
|
+
s.email = ['benny@itws.de']
|
12
|
+
s.description = 'Helps you to get back in a project after some idle time or to contribute to a OpenSource project by telling you what you can do on the project.'
|
13
|
+
s.summary = s.description
|
14
|
+
s.homepage = 'https://github.com/phortx/WhatToDo'
|
15
|
+
s.license = 'MIT'
|
16
|
+
|
17
|
+
s.required_ruby_version = '>= 1.9.3'
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split($/)
|
20
|
+
s.require_paths = ['lib']
|
21
|
+
s.executables = ['whatToDo']
|
22
|
+
s.extra_rdoc_files = ['README.md']
|
23
|
+
|
24
|
+
s.add_runtime_dependency 'colored'
|
25
|
+
|
26
|
+
s.add_development_dependency 'bundler', '~> 1.3'
|
27
|
+
s.add_development_dependency 'rake'
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: whatToDo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Benjamin Kammerl
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: colored
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: bundler
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.3'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.3'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Helps you to get back in a project after some idle time or to contribute
|
63
|
+
to a OpenSource project by telling you what you can do on the project.
|
64
|
+
email:
|
65
|
+
- benny@itws.de
|
66
|
+
executables:
|
67
|
+
- whatToDo
|
68
|
+
extensions: []
|
69
|
+
extra_rdoc_files:
|
70
|
+
- README.md
|
71
|
+
files:
|
72
|
+
- .gitignore
|
73
|
+
- Gemfile
|
74
|
+
- Gemfile.lock
|
75
|
+
- LICENSE
|
76
|
+
- README.md
|
77
|
+
- Rakefile
|
78
|
+
- bin/whatToDo
|
79
|
+
- lib/whatToDo.rb
|
80
|
+
- lib/whatToDo/check/bootstrap.rb
|
81
|
+
- lib/whatToDo/check/readme.rb
|
82
|
+
- lib/whatToDo/check/todo.rb
|
83
|
+
- lib/whatToDo/check_manager.rb
|
84
|
+
- lib/whatToDo/facet/git.rb
|
85
|
+
- lib/whatToDo/facet/ruby.rb
|
86
|
+
- lib/whatToDo/facet_analyzer.rb
|
87
|
+
- lib/whatToDo/util.rb
|
88
|
+
- lib/whatToDo/version.rb
|
89
|
+
- screenshot.png
|
90
|
+
- whatToDo.gemspec
|
91
|
+
homepage: https://github.com/phortx/WhatToDo
|
92
|
+
licenses:
|
93
|
+
- MIT
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.9.3
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 1.8.25
|
113
|
+
signing_key:
|
114
|
+
specification_version: 3
|
115
|
+
summary: Helps you to get back in a project after some idle time or to contribute
|
116
|
+
to a OpenSource project by telling you what you can do on the project.
|
117
|
+
test_files: []
|