gitscribe 0.0.2
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.
- data/README.markdown +16 -0
- data/VERSION.yml +4 -0
- data/bin/gitscribe +8 -0
- data/lib/gitscribe.rb +51 -0
- data/lib/gitscribe/models.rb +67 -0
- data/lib/gitscribe/options.rb +39 -0
- data/lib/gitscribe/template.erb +20 -0
- data/test/gitscribe_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +72 -0
data/README.markdown
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# GitScribe: Create tutorials and articles with Git
|
|
2
|
+
|
|
3
|
+
## Installing
|
|
4
|
+
|
|
5
|
+
# Run the following if you haven't done so before:
|
|
6
|
+
gem sources -a http://gems.github.com
|
|
7
|
+
# Install the gem:
|
|
8
|
+
sudo gem install dima-gitscribe
|
|
9
|
+
|
|
10
|
+
## Using
|
|
11
|
+
|
|
12
|
+
gitscribe --title 'Working with RestfulX Model Attachments' rx_model_attachments
|
|
13
|
+
|
|
14
|
+
# License
|
|
15
|
+
|
|
16
|
+
Copyright (c) 2009 Dima Berastau. Released under MIT License
|
data/VERSION.yml
ADDED
data/bin/gitscribe
ADDED
data/lib/gitscribe.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'git'
|
|
2
|
+
require 'erb'
|
|
3
|
+
require 'gitscribe/options'
|
|
4
|
+
require 'gitscribe/models'
|
|
5
|
+
|
|
6
|
+
class GitScribe
|
|
7
|
+
class << self
|
|
8
|
+
def run!(*arguments)
|
|
9
|
+
options = GitScribe::Options.new(arguments)
|
|
10
|
+
|
|
11
|
+
if options[:show_help]
|
|
12
|
+
$stderr.puts options.opts
|
|
13
|
+
return 1
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
unless arguments.size == 1
|
|
17
|
+
$stderr.puts options.opts
|
|
18
|
+
return 1
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
g = Git.open(arguments.first)
|
|
22
|
+
|
|
23
|
+
tags = Array.new
|
|
24
|
+
g.tags.sort_by { |x| g.object(x.objectish).date }.each { |t| tags << t.name }
|
|
25
|
+
|
|
26
|
+
chapters = Array.new
|
|
27
|
+
if tags.empty?
|
|
28
|
+
chapter = Chapter.new
|
|
29
|
+
g.log.each { |c| add_section(chapter.sections, c) }
|
|
30
|
+
chapters << chapter
|
|
31
|
+
else
|
|
32
|
+
tags.each_index do |i|
|
|
33
|
+
chapter = Chapter.new(tags[i])
|
|
34
|
+
g.log.between(tags[i], tags[i + 1]).each { |c| add_section(chapter.sections, c) } if i + 1 < tags.size
|
|
35
|
+
chapters << chapter if !chapter.sections.empty?
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
template = File.read(File.dirname(__FILE__) + "/gitscribe/template.erb")
|
|
40
|
+
|
|
41
|
+
f = File.new(options[:output], "w+")
|
|
42
|
+
f.puts(ERB.new(template).result(binding))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def add_section(target, c)
|
|
46
|
+
target << GitScribe::Section.new(c.message(), c.parent().diff(c)) if c.parent()
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
class GitScribe
|
|
2
|
+
class Chapter
|
|
3
|
+
attr_accessor :title, :sections
|
|
4
|
+
|
|
5
|
+
def initialize(title = 'Chapter X', sections = [])
|
|
6
|
+
@title, @sections = title, sections
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class Section
|
|
11
|
+
attr_reader :message
|
|
12
|
+
|
|
13
|
+
def initialize(message, diff)
|
|
14
|
+
@message, @diff = message, diff
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def diff
|
|
18
|
+
@diff.select { |f| valid_file(f.path) }.map do |f|
|
|
19
|
+
type = f.type == "new" ? file_type(f.path) : "diff"
|
|
20
|
+
code, target_file = parse_diff(f.patch, f.type)
|
|
21
|
+
"File: #{target_file}\n\n{% highlight #{type} %}\n#{code}\n{% endhighlight %}\n\n"
|
|
22
|
+
end.join
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
def parse_diff(patch, type)
|
|
27
|
+
offset = patch.index(/@@ -\d+,\d+ \+\d+,\d+ @@/) - 1
|
|
28
|
+
header = patch.slice!(0 .. offset)
|
|
29
|
+
target_file = /diff --git a\/(.*?) b\/(.*?)/.match(header)[1]
|
|
30
|
+
patch = patch.split("\n").select { |l|!l.include?("No newline at end of file") }.map do |l|
|
|
31
|
+
l = l[1..-1] unless l.match(/@@ -\d+,\d+ \+\d+,\d+ @@/)
|
|
32
|
+
#split(l)
|
|
33
|
+
end.join("\n") if type == "new"
|
|
34
|
+
patch = patch.gsub(/\t/m, " ")
|
|
35
|
+
[patch, target_file]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# This is pretty doggy, would be nice to have a decent lexical analizer that can
|
|
39
|
+
# reformat code based on a width parameter
|
|
40
|
+
def split(line)
|
|
41
|
+
line.split("\n").map do |l|
|
|
42
|
+
if l.size > 80
|
|
43
|
+
offset = l.rindex(/\s/)
|
|
44
|
+
first_part = l.slice!(0 .. offset)
|
|
45
|
+
"#{first_part}\n #{l}"
|
|
46
|
+
else
|
|
47
|
+
l
|
|
48
|
+
end
|
|
49
|
+
end.join("\n")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# needs to be configurable
|
|
53
|
+
def valid_file(f)
|
|
54
|
+
f =~ /\.rb$|\.mxml$|\.as$/
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def file_type(f)
|
|
58
|
+
result = case f
|
|
59
|
+
when /.rb$/ : "ruby"
|
|
60
|
+
when /.mxml$/ : "xml"
|
|
61
|
+
when /.as$/ : "as3"
|
|
62
|
+
else
|
|
63
|
+
"unknown"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
class GitScribe
|
|
2
|
+
class Options < Hash
|
|
3
|
+
attr_reader :opts
|
|
4
|
+
|
|
5
|
+
def initialize(args)
|
|
6
|
+
super()
|
|
7
|
+
|
|
8
|
+
self[:title] = "Cool Tutorial"
|
|
9
|
+
self[:location] = "Vancouver, BC"
|
|
10
|
+
|
|
11
|
+
@opts = OptionParser.new do |o|
|
|
12
|
+
o.banner = "Usage: #{File.basename($0)} [options] reponame\ne.g. #{File.basename($0)} cool-tutorial"
|
|
13
|
+
|
|
14
|
+
o.on('--output [FILE]', 'Output file to generate blog post to') do |output|
|
|
15
|
+
self[:output] = output
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
o.on('--title [TITLE]', 'Blog post title to use', "Default: #{self[:title]}") do |title|
|
|
19
|
+
self[:title] = title
|
|
20
|
+
self[:output] = default_output unless self[:output]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
o.on('--location [LOCATION]', 'Add geo location to the blog post', "Default: #{self[:location]}") do |location|
|
|
24
|
+
self[:location] = location
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
o.on_tail('-h', '--help', 'display this help and exit') do
|
|
28
|
+
self[:show_help] = true
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@opts.parse!(args)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def default_output
|
|
36
|
+
"#{Date.today.strftime("%Y-%m-%d")}-#{self[:title].gsub(/\s/, '-').downcase}.textile"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: post
|
|
3
|
+
title: <%= options[:title] %>
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
h1. {{ page.title }}
|
|
7
|
+
|
|
8
|
+
p(meta). <%= Date.today.strftime("%d %b %Y") %> - <%= options[:location] %>
|
|
9
|
+
|
|
10
|
+
<% chapters.each do |chapter| %>
|
|
11
|
+
h2. <%= chapter.title %>
|
|
12
|
+
|
|
13
|
+
<% chapter.sections.reverse.each do |section| %>
|
|
14
|
+
h3. Section
|
|
15
|
+
|
|
16
|
+
<%= section.message %>
|
|
17
|
+
|
|
18
|
+
<%= section.diff %>
|
|
19
|
+
<% end %>
|
|
20
|
+
<% end %>
|
data/test/test_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: gitscribe
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Dima Berastau
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-02-22 00:00:00 -08:00
|
|
13
|
+
default_executable: gitscribe
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: schacon-git
|
|
17
|
+
type: :runtime
|
|
18
|
+
version_requirement:
|
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
20
|
+
requirements:
|
|
21
|
+
- - ">="
|
|
22
|
+
- !ruby/object:Gem::Version
|
|
23
|
+
version: "0"
|
|
24
|
+
version:
|
|
25
|
+
description:
|
|
26
|
+
email: dima@ruboss.com
|
|
27
|
+
executables:
|
|
28
|
+
- gitscribe
|
|
29
|
+
extensions: []
|
|
30
|
+
|
|
31
|
+
extra_rdoc_files: []
|
|
32
|
+
|
|
33
|
+
files:
|
|
34
|
+
- README.markdown
|
|
35
|
+
- VERSION.yml
|
|
36
|
+
- bin/gitscribe
|
|
37
|
+
- lib/gitscribe
|
|
38
|
+
- lib/gitscribe/models.rb
|
|
39
|
+
- lib/gitscribe/options.rb
|
|
40
|
+
- lib/gitscribe/template.erb
|
|
41
|
+
- lib/gitscribe.rb
|
|
42
|
+
- test/gitscribe_test.rb
|
|
43
|
+
- test/test_helper.rb
|
|
44
|
+
has_rdoc: true
|
|
45
|
+
homepage: http://github.com/dima/gitscribe
|
|
46
|
+
post_install_message:
|
|
47
|
+
rdoc_options:
|
|
48
|
+
- --inline-source
|
|
49
|
+
- --charset=UTF-8
|
|
50
|
+
require_paths:
|
|
51
|
+
- lib
|
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
|
+
requirements:
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: "0"
|
|
57
|
+
version:
|
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: "0"
|
|
63
|
+
version:
|
|
64
|
+
requirements: []
|
|
65
|
+
|
|
66
|
+
rubyforge_project:
|
|
67
|
+
rubygems_version: 1.3.1
|
|
68
|
+
signing_key:
|
|
69
|
+
specification_version: 2
|
|
70
|
+
summary: Create code-intensive tutorials and articles with Git
|
|
71
|
+
test_files: []
|
|
72
|
+
|