bookingit 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/Gemfile.lock +7 -1
- data/README.rdoc +86 -37
- data/TODO.md +7 -0
- data/bin/bookingit +19 -58
- data/bookingit.gemspec +2 -0
- data/features/bookingit.feature +149 -16
- data/features/step_definitions/bookinggit_steps.rb +18 -0
- data/features/support/env.rb +5 -1
- data/lib/bookingit.rb +5 -0
- data/lib/bookingit/book.rb +94 -0
- data/lib/bookingit/code_block_interpreter.rb +114 -0
- data/lib/bookingit/config.rb +62 -28
- data/lib/bookingit/errors.rb +16 -0
- data/lib/bookingit/renderer.rb +173 -39
- data/lib/bookingit/shell_command.rb +30 -0
- data/lib/bookingit/version.rb +1 -1
- data/lib/bookingit/views.rb +8 -0
- data/lib/bookingit/views/base_view.rb +12 -0
- data/lib/bookingit/views/code_view.rb +16 -0
- data/lib/bookingit/views/footer_view.rb +14 -0
- data/lib/bookingit/views/header_view.rb +17 -0
- data/lib/bookingit/views/index_view.rb +20 -0
- data/templates/block_code.html.mustache +1 -0
- data/templates/footer.html.mustache +37 -0
- data/templates/header.html.mustache +16 -0
- data/templates/index.html.mustache +27 -0
- data/templates/stylesheets.html.mustache +3 -0
- data/templates/syntax_highlighting.html.mustache +3 -0
- data/test/book_test.rb +20 -0
- data/test/config_test.rb +43 -35
- data/test/renderer_test.rb +173 -23
- data/test/test_helper.rb +2 -0
- metadata +50 -2
@@ -24,3 +24,21 @@ Given(/^this config file:$/) do |string|
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
Given(/^a git repo "(.*?)" in "(.*?)" containing the file "(.*?)" and a tag "(.*?)"$/) do |repo_name, repo_basedir, file_name, tag_name|
|
28
|
+
FileUtils.chdir "tmp/aruba" do
|
29
|
+
FileUtils.mkdir repo_basedir
|
30
|
+
@dirs_created << repo_basedir
|
31
|
+
FileUtils.chdir repo_basedir do
|
32
|
+
FileUtils.mkdir repo_name
|
33
|
+
FileUtils.chdir repo_name do
|
34
|
+
File.open(file_name,'w') do |file|
|
35
|
+
file.puts "Some stuff and whatnot"
|
36
|
+
end
|
37
|
+
system "git init"
|
38
|
+
system "git add #{file_name}"
|
39
|
+
system "git commit -m 'initial'"
|
40
|
+
system "git tag #{tag_name}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/features/support/env.rb
CHANGED
@@ -8,12 +8,16 @@ Before do
|
|
8
8
|
@puts = true
|
9
9
|
@original_rubylib = ENV['RUBYLIB']
|
10
10
|
@files_created = []
|
11
|
+
@dirs_created = []
|
11
12
|
ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
|
12
13
|
end
|
13
14
|
|
14
15
|
After do
|
15
16
|
ENV['RUBYLIB'] = @original_rubylib
|
16
17
|
@files_created.each do |file|
|
17
|
-
FileUtils.rm file
|
18
|
+
FileUtils.rm file if File.exists?(file)
|
19
|
+
end
|
20
|
+
@dirs_created.each do |dir|
|
21
|
+
FileUtils.rm_rf dir if File.exists?(dir)
|
18
22
|
end
|
19
23
|
end
|
data/lib/bookingit.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'bookingit/views'
|
1
2
|
require 'bookingit/version.rb'
|
3
|
+
require 'bookingit/errors.rb'
|
4
|
+
require 'bookingit/code_block_interpreter.rb'
|
5
|
+
require 'bookingit/shell_command.rb'
|
2
6
|
require 'bookingit/renderer.rb'
|
3
7
|
require 'bookingit/config.rb'
|
8
|
+
require 'bookingit/book.rb'
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Bookingit
|
2
|
+
class Book
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
@output_dir = 'book'
|
6
|
+
end
|
7
|
+
|
8
|
+
def render_html!
|
9
|
+
mkdir @output_dir unless Dir.exists?(@output_dir)
|
10
|
+
|
11
|
+
rendering_config = @config.rendering_config
|
12
|
+
rendering_config[:cache] = File.expand_path('cache') if @config.cache
|
13
|
+
renderer = Bookingit::Renderer.new(@config)
|
14
|
+
@redcarpet = Redcarpet::Markdown.new(renderer, no_intra_emphasis: true,
|
15
|
+
tables: true,
|
16
|
+
fenced_code_blocks: true,
|
17
|
+
autolink: true,
|
18
|
+
strikethrough: true,
|
19
|
+
superscript: true)
|
20
|
+
|
21
|
+
toc = parse_chapters_to_get_headers(renderer)
|
22
|
+
generate_chapters(renderer)
|
23
|
+
generate_toc(toc,renderer.stylesheets,renderer.theme)
|
24
|
+
copy_assets(renderer)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def parse_chapters_to_get_headers(renderer)
|
30
|
+
toc = {}
|
31
|
+
each_chapter do |matter,contents,chapter|
|
32
|
+
toc[matter] ||= []
|
33
|
+
renderer.current_chapter = chapter
|
34
|
+
@redcarpet.render(contents)
|
35
|
+
chapter.title = Array(renderer.headers[1]).first
|
36
|
+
toc[matter] << chapter
|
37
|
+
end
|
38
|
+
toc
|
39
|
+
end
|
40
|
+
|
41
|
+
def each_chapter(&block)
|
42
|
+
%w(front_matter main_matter back_matter).each do |matter|
|
43
|
+
@config.send(matter).chapters.each do |chapter|
|
44
|
+
block.call(matter,File.read(chapter.markdown_path),chapter)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def generate_chapters(renderer)
|
50
|
+
each_chapter do |_,contents,chapter|
|
51
|
+
output_file = chapter.relative_url
|
52
|
+
renderer.current_chapter = chapter
|
53
|
+
File.open(File.join(@output_dir,output_file),'w') do |file|
|
54
|
+
file.puts @redcarpet.render(contents)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def generate_toc(toc,stylesheets,theme)
|
60
|
+
if @config.templates["index"] =~ /^\//
|
61
|
+
Views::IndexView.template_path = File.dirname(@config.templates["index"])
|
62
|
+
Views::IndexView.template_name = File.basename(@config.templates["index"])
|
63
|
+
else
|
64
|
+
Views::IndexView.template_name = @config.templates["index"]
|
65
|
+
end
|
66
|
+
view = Views::IndexView.new(stylesheets,
|
67
|
+
theme,
|
68
|
+
toc['front_matter'],
|
69
|
+
toc['main_matter'],
|
70
|
+
toc['back_matter'],
|
71
|
+
@config)
|
72
|
+
File.open(File.join(@output_dir,'index.html'),'w') do |index|
|
73
|
+
index.puts view.render
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def copy_assets(renderer)
|
78
|
+
@config.rendering_config[:stylesheets].each do |stylesheet|
|
79
|
+
cp stylesheet, @output_dir
|
80
|
+
end
|
81
|
+
renderer.images.each do |image|
|
82
|
+
if File.exists?(image)
|
83
|
+
dest_dir = File.join(@output_dir,File.dirname(image))
|
84
|
+
unless File.exists? dest_dir
|
85
|
+
mkdir_p dest_dir
|
86
|
+
end
|
87
|
+
cp image,dest_dir
|
88
|
+
else
|
89
|
+
$stderr.puts "Missing image #{image}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Bookingit
|
2
|
+
class CodeBlockInterpreter
|
3
|
+
def initialize(code)
|
4
|
+
@code = code.strip
|
5
|
+
@result = nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def when_file(&block)
|
9
|
+
if @code =~ /^\s*file:\/\/(.*)$/
|
10
|
+
path = $1
|
11
|
+
@result = block.call(path)
|
12
|
+
end
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def when_file_in_git(&block)
|
17
|
+
when_git_reference do |repo_path,path_in_repo,reference|
|
18
|
+
if reference !~ /^(.+)\.\.(.+)$/ && reference !~ /^(.+)\!(.+)$/ && reference !~ /^\.\.(.+)$/
|
19
|
+
chdir repo_path do
|
20
|
+
@result = block.call(path_in_repo,reference)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def when_git_diff(&block)
|
28
|
+
when_git_reference do |repo_path,path_in_repo,reference|
|
29
|
+
if reference =~ /^(.+)\.\.(.+)$/
|
30
|
+
chdir repo_path do
|
31
|
+
@result = block.call(path_in_repo,reference)
|
32
|
+
end
|
33
|
+
elsif reference =~ /^\.\.(.+)$/
|
34
|
+
tag_or_sha = $1
|
35
|
+
chdir repo_path do
|
36
|
+
@result = block.call(path_in_repo,"#{tag_or_sha}^..#{tag_or_sha}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def when_shell_command_in_git(&block)
|
44
|
+
when_git_reference do |repo_path,path_in_repo,reference|
|
45
|
+
if reference =~ /^([^!]+)\!(.+)$/
|
46
|
+
reference = $1
|
47
|
+
command,exit_type = parse_shell_command($2)
|
48
|
+
chdir repo_path do
|
49
|
+
@result = block.call(reference,shell_command(path: path_in_repo,command: command, exit_type: exit_type))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def when_shell_command(&block)
|
56
|
+
if @code.strip =~ /^\s*sh:\/\/(.+)#([^#]+)$/
|
57
|
+
path = $1
|
58
|
+
command,exit_type = parse_shell_command($2)
|
59
|
+
@result = block.call(shell_command(path: path,command: command, exit_type: exit_type))
|
60
|
+
end
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def otherwise(&block)
|
65
|
+
@result = block.call if @result.nil?
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
def result
|
70
|
+
raise "You didn't handle every possible case" if @result.nil?
|
71
|
+
@result
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def shell_command(path: nil, command: nil, exit_type: nil)
|
77
|
+
ShellCommand.new(path: path,command: command) do |exit_status|
|
78
|
+
case exit_type
|
79
|
+
when :zero
|
80
|
+
exit_status == 0
|
81
|
+
when :nonzero
|
82
|
+
exit_status != 0
|
83
|
+
else
|
84
|
+
raise "unknown exit type #{exit_type}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def parse_shell_command(shell_command)
|
90
|
+
if shell_command =~ /(^.*)!([^!]+)$/
|
91
|
+
[$1,$2.to_sym]
|
92
|
+
else
|
93
|
+
[shell_command,:zero]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def when_git_reference(&block)
|
98
|
+
if @code =~ /^\s*git:\/\/(.*)$/
|
99
|
+
path = $1
|
100
|
+
if path =~ /(^.*).git\/(.*)#([^#]+)$/
|
101
|
+
repo_path = $1
|
102
|
+
path_in_repo = $2
|
103
|
+
path_in_repo = '.' if String(path_in_repo).strip == ''
|
104
|
+
reference = $3
|
105
|
+
block.call(repo_path,path_in_repo,reference)
|
106
|
+
else
|
107
|
+
raise "You must provide a SHA1 or tagname: #{path}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
data/lib/bookingit/config.rb
CHANGED
@@ -7,50 +7,84 @@ module Bookingit
|
|
7
7
|
|
8
8
|
attr_reader :front_matter,
|
9
9
|
:main_matter,
|
10
|
-
:back_matter
|
10
|
+
:back_matter,
|
11
|
+
:rendering_config,
|
12
|
+
:cache,
|
13
|
+
:options,
|
14
|
+
:templates
|
11
15
|
|
12
16
|
def initialize(config_json,root_dir)
|
13
17
|
config_hash = JSON.parse(config_json)
|
14
18
|
|
15
|
-
@front_matter
|
16
|
-
@main_matter
|
17
|
-
@back_matter
|
19
|
+
@front_matter = Matter.new(config_hash.delete('front_matter'),root_dir)
|
20
|
+
@main_matter = Matter.new(config_hash.delete('main_matter'),root_dir)
|
21
|
+
@back_matter = Matter.new(config_hash.delete('back_matter'),root_dir)
|
22
|
+
@templates = config_hash.delete("templates") || {}
|
23
|
+
@templates["index"] ||= "index.html"
|
24
|
+
@rendering_config = create_rendering_config(config_hash.delete('rendering'))
|
25
|
+
@cache = false
|
26
|
+
@options = config_hash
|
27
|
+
|
28
|
+
all_chapters = (@front_matter.chapters + @main_matter.chapters + @back_matter.chapters)
|
29
|
+
all_chapters.each_with_index do |chapter,i|
|
30
|
+
if i > 0
|
31
|
+
all_chapters[i-1].next_chapter = chapter
|
32
|
+
chapter.previous_chapter = all_chapters[i-1]
|
33
|
+
end
|
34
|
+
if i < (all_chapters.size-1)
|
35
|
+
all_chapters[i+1].previous_chapter = chapter
|
36
|
+
chapter.next_chapter = all_chapters[i+1]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def cache=(cache)
|
42
|
+
@cache = cache
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def create_rendering_config(raw_config)
|
48
|
+
raw_config ||= {}
|
49
|
+
rendering_config = {}
|
50
|
+
rendering_config[:stylesheets] = Array(raw_config['stylesheets'])
|
51
|
+
rendering_config[:basedir] = raw_config['git_repos_basedir']
|
52
|
+
rendering_config[:languages] = Hash[(raw_config['languages'] || {}).map { |match,language|
|
53
|
+
if match =~ /^\/(.+)\/$/
|
54
|
+
[Regexp.new($1),language]
|
55
|
+
else
|
56
|
+
[match,language]
|
57
|
+
end
|
58
|
+
}]
|
59
|
+
rendering_config[:theme] = raw_config['syntax_theme']
|
60
|
+
|
61
|
+
rendering_config
|
18
62
|
end
|
19
63
|
|
20
64
|
class Matter
|
21
65
|
attr_reader :chapters
|
22
|
-
def initialize(
|
23
|
-
@chapters = Array(
|
24
|
-
Chapter.new(
|
66
|
+
def initialize(chapter_filenames,root_dir)
|
67
|
+
@chapters = Array(chapter_filenames).map { |chapter_filename|
|
68
|
+
Chapter.new(markdown_path: File.join(root_dir,chapter_filename))
|
25
69
|
}
|
26
70
|
end
|
27
71
|
end
|
28
72
|
|
29
73
|
class Chapter
|
30
|
-
attr_reader :sections
|
31
|
-
|
32
|
-
|
33
|
-
def initialize(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
if files.size == 1
|
38
|
-
@sections = []
|
39
|
-
@path = files[0]
|
40
|
-
else
|
41
|
-
@sections = files.map { |file|
|
42
|
-
Section.new(file)
|
43
|
-
}
|
44
|
-
end
|
74
|
+
attr_reader :markdown_path, :relative_url, :sections
|
75
|
+
attr_accessor :title, :previous_chapter, :next_chapter
|
76
|
+
|
77
|
+
def initialize(markdown_path: nil, relative_url: nil)
|
78
|
+
@markdown_path = markdown_path
|
79
|
+
@relative_url = relative_url || (File.basename(markdown_path, File.extname(markdown_path)) + ".html")
|
80
|
+
@sections = []
|
45
81
|
end
|
46
|
-
end
|
47
82
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@
|
83
|
+
def add_section(title,anchor)
|
84
|
+
section = Chapter.new(relative_url: self.relative_url + "##{anchor}")
|
85
|
+
section.title = title
|
86
|
+
@sections << section
|
52
87
|
end
|
53
88
|
end
|
54
89
|
end
|
55
|
-
|
56
90
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'gli'
|
2
|
+
module Bookingit
|
3
|
+
class UnexpectedShellCommandExit < StandardError
|
4
|
+
include GLI::StandardException
|
5
|
+
attr_reader :command, :stdout, :stderr
|
6
|
+
def initialize(command,stdout,stderr)
|
7
|
+
@command = command
|
8
|
+
@stdout = stdout
|
9
|
+
@stderr = stderr
|
10
|
+
end
|
11
|
+
|
12
|
+
def exit_code
|
13
|
+
126
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/bookingit/renderer.rb
CHANGED
@@ -6,63 +6,197 @@ module Bookingit
|
|
6
6
|
class Renderer < Redcarpet::Render::HTML
|
7
7
|
include FileUtils
|
8
8
|
|
9
|
-
|
9
|
+
def initialize(config)
|
10
|
+
super()
|
11
|
+
options = config.rendering_config
|
12
|
+
additional_languages = Hash[(options[:languages] || {}).map { |ext_or_regexp,language|
|
13
|
+
if ext_or_regexp.kind_of? String
|
14
|
+
[/#{ext_or_regexp}$/,language]
|
15
|
+
else
|
16
|
+
[ext_or_regexp,language]
|
17
|
+
end
|
18
|
+
}]
|
19
|
+
@language_identifiers = EXTENSION_TO_LANGUAGE.merge(additional_languages)
|
20
|
+
@basedir = String(options[:basedir]).strip
|
21
|
+
@basedir = '.' if @basedir == ''
|
22
|
+
@stylesheets = Array(options[:stylesheets])
|
23
|
+
@theme = options[:theme] || "default"
|
24
|
+
@cachedir = options[:cache]
|
25
|
+
@config = config
|
26
|
+
@images = []
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :headers, :stylesheets, :theme, :images
|
30
|
+
|
31
|
+
def current_chapter=(chapter)
|
32
|
+
@chapter = chapter
|
33
|
+
end
|
34
|
+
|
10
35
|
def header(text,header_level,anchor)
|
11
36
|
@headers[header_level] ||= []
|
12
37
|
@headers[header_level] << text
|
13
|
-
|
38
|
+
if header_level == 2
|
39
|
+
@chapter.add_section(text,anchor)
|
40
|
+
end
|
41
|
+
"<a name='#{anchor}'></a><h#{header_level+1}>#{text}</h#{header_level+1}>"
|
42
|
+
end
|
43
|
+
|
44
|
+
def image(link, title, alt_text)
|
45
|
+
title = title.gsub(/'/,'"') if title
|
46
|
+
@images << link
|
47
|
+
"<img src='#{link}' alt='#{alt_text}' title='#{title}'>"
|
14
48
|
end
|
15
49
|
|
16
50
|
def doc_header
|
17
51
|
@headers = {}
|
18
|
-
|
52
|
+
Views::HeaderView.new(@stylesheets,@theme,@config).render
|
53
|
+
end
|
54
|
+
|
55
|
+
def doc_footer
|
56
|
+
Views::FooterView.new(@chapter,@config).render
|
19
57
|
end
|
20
58
|
|
21
59
|
EXTENSION_TO_LANGUAGE = {
|
22
|
-
|
23
|
-
|
24
|
-
|
60
|
+
/\.rb$/ => 'ruby',
|
61
|
+
/\.html$/ => 'html',
|
62
|
+
/\.scala$/ => 'scala',
|
63
|
+
/Gemfile$/ => 'ruby',
|
25
64
|
}
|
65
|
+
|
66
|
+
def identify_language(path)
|
67
|
+
@language_identifiers.select { |matcher,language|
|
68
|
+
path =~ matcher
|
69
|
+
}.values.first
|
70
|
+
end
|
71
|
+
|
72
|
+
|
26
73
|
def block_code(code, language)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
language =
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
74
|
+
result = nil
|
75
|
+
filename = nil
|
76
|
+
chdir @basedir do
|
77
|
+
code,language,filename = CodeBlockInterpreter.new(code)
|
78
|
+
.when_file( &cache(:read_file))
|
79
|
+
.when_git_diff( &cache(:read_git_diff))
|
80
|
+
.when_shell_command_in_git(&cache(:run_shell_command_in_git))
|
81
|
+
.when_file_in_git( &cache(:read_file_in_git))
|
82
|
+
.when_shell_command( &cache(:run_shell_command))
|
83
|
+
.otherwise {
|
84
|
+
[code,language,nil]
|
85
|
+
}.result
|
86
|
+
end
|
87
|
+
Views::CodeView.new(code,filename,language,@config).render.strip
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def cache(method_name)
|
93
|
+
->(*args) {
|
94
|
+
if @cachedir && File.exist?(cached_filename(*args))
|
95
|
+
puts "Pulling from cache..."
|
96
|
+
lines = File.read(cached_filename(*args)).split(/\n/)
|
97
|
+
language = lines.shift
|
98
|
+
filename = lines.shift
|
99
|
+
[lines.join("\n") + "\n",language,filename]
|
100
|
+
else
|
101
|
+
code,language,filename = method(method_name).(*args)
|
102
|
+
if @cachedir
|
103
|
+
FileUtils.mkdir_p(@cachedir) unless File.exist?(@cachedir)
|
104
|
+
File.open(cached_filename(*args),'w') do |file|
|
105
|
+
file.puts language
|
106
|
+
file.puts filename
|
107
|
+
file.puts code
|
46
108
|
end
|
109
|
+
puts "Cached output"
|
47
110
|
end
|
111
|
+
[code,language,filename]
|
112
|
+
end
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
116
|
+
def cached_filename(*args)
|
117
|
+
args = args.map { |arg|
|
118
|
+
case arg
|
119
|
+
when ShellCommand
|
120
|
+
[arg.command,arg.expected_exit_status].join("_")
|
48
121
|
else
|
49
|
-
|
122
|
+
arg
|
50
123
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
124
|
+
}
|
125
|
+
File.join(@cachedir,args.join('__').gsub(/[#\/\!\s><]/,'_'))
|
126
|
+
end
|
127
|
+
|
128
|
+
def at_version_in_git(reference,&block)
|
129
|
+
ShellCommand.new(command: "git checkout #{reference} 2>&1").run!
|
130
|
+
block.call
|
131
|
+
ShellCommand.new(command: "git checkout master 2>&1").run!
|
132
|
+
end
|
133
|
+
|
134
|
+
def capture_command_output(path,command,exit_type=:zero)
|
135
|
+
shell_command = ShellCommand.new(command: command,path: path) do |exit_status|
|
136
|
+
case exit_type
|
137
|
+
when :zero
|
138
|
+
exit_status == 0
|
139
|
+
when :nonzero
|
140
|
+
exit_status != 0
|
141
|
+
else
|
142
|
+
raise "unknown exit type #{exit_type}"
|
58
143
|
end
|
59
144
|
end
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
145
|
+
shell_command.run!
|
146
|
+
["> #{command}\n#{shell_command.stdout}",'shell']
|
147
|
+
end
|
148
|
+
|
149
|
+
def read_file(path)
|
150
|
+
filename = path
|
151
|
+
[File.read(path),identify_language(path),filename]
|
152
|
+
end
|
153
|
+
|
154
|
+
def read_git_diff(path_in_repo,reference)
|
155
|
+
puts "Calculating git diff #{reference}"
|
156
|
+
filename = path_in_repo
|
157
|
+
shell_command = ShellCommand.new(command: "git diff #{reference} #{path_in_repo}")
|
158
|
+
shell_command.run!
|
159
|
+
[ shell_command.stdout, 'diff', filename ]
|
160
|
+
end
|
161
|
+
|
162
|
+
def run_shell_command_in_git(reference,shell_command)
|
163
|
+
code = nil
|
164
|
+
at_version_in_git(reference) do
|
165
|
+
shell_command.run!
|
166
|
+
code = "> #{shell_command.command}\n#{shell_command.stdout}"
|
167
|
+
end
|
168
|
+
[code,'shell']
|
169
|
+
end
|
170
|
+
|
171
|
+
def read_file_in_git(path_in_repo,reference)
|
172
|
+
puts "Getting file at #{reference}"
|
173
|
+
code = nil
|
174
|
+
filename = path_in_repo
|
175
|
+
at_version_in_git(reference) do
|
176
|
+
code = File.read(path_in_repo)
|
177
|
+
end
|
178
|
+
[code, identify_language(path_in_repo),filename]
|
179
|
+
end
|
180
|
+
|
181
|
+
def run_shell_command(shell_command)
|
182
|
+
shell_command.run!
|
183
|
+
["> #{shell_command.command}\n#{shell_command.stdout}",'shell']
|
184
|
+
end
|
185
|
+
|
186
|
+
def css_class(language)
|
187
|
+
if language.nil? || language.strip == ''
|
188
|
+
""
|
189
|
+
else
|
190
|
+
" class=\"language-#{language}\""
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def filename_footer(filename)
|
195
|
+
if filename && filename.strip != ''
|
196
|
+
%{<footer><h1>#{filename}</h1></footer>}
|
197
|
+
else
|
198
|
+
''
|
199
|
+
end
|
66
200
|
end
|
67
201
|
end
|
68
202
|
end
|