gitscribe 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 0
3
+ :patch: 2
4
+ :major: 0
data/bin/gitscribe ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'optparse'
4
+
5
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
6
+ require 'gitscribe'
7
+
8
+ GitScribe.run!(*ARGV)
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 %>
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class GitscribeTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+ require 'mocha'
5
+
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'gitscribe'
8
+
9
+ class Test::Unit::TestCase
10
+ end
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
+