oleg 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bf4f5f87c6d337bb62e7b3df44db52ec21b28b6d
4
- data.tar.gz: 38d29d3088c021488ee771d61093893011964e80
3
+ metadata.gz: fe515e58859a107bbab71359a195c02320c7103f
4
+ data.tar.gz: 9e6be5fa4d23ca96d0bb5818bec9aaf4d5f37f25
5
5
  SHA512:
6
- metadata.gz: a245d260ca274707448ac4f2c3671f46c4cb8b6a57eab49fa68087b9a65ac876cc3c1ff2a651fc9c814a371ef305e2dadf3cc973ca585366fea5dc81d38fb731
7
- data.tar.gz: c120b9ab3436791c35bfe5642e050f7005375cd6c95b36f49cc3c29dffa9334bf5b555947dfcff9f113cea243562c78f83cb296e631397a1300d29ce13e3d4ab
6
+ metadata.gz: 0616f537ca77cb5e405e4704f50043e54d8a217fe8e29de6b8e08859063bf46ebf11677461b23b05214e9b0e817c17d0264eaee172bd0b95876e6f9da0eb2a31
7
+ data.tar.gz: f315be05ebda93d8e3ac796f8456f872b39f3b53857d9068272a6b8629fbcb241b41cc099bc12c027893bacd81f52846bed34aaf4514623fd0659cebfeb554c3
data/lib/leg.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'fileutils'
2
2
  require 'yaml'
3
3
  require 'rugged'
4
+ require 'redcarpet'
5
+ require 'rouge'
4
6
 
5
7
  module Leg
6
8
  end
data/lib/leg/commands.rb CHANGED
@@ -5,8 +5,10 @@ end
5
5
  require 'leg/commands/base_command'
6
6
 
7
7
  require 'leg/commands/diff'
8
+ require 'leg/commands/doc'
8
9
  require 'leg/commands/help'
9
10
  require 'leg/commands/pieces'
11
+ require 'leg/commands/fancy'
10
12
  require 'leg/commands/ref'
11
13
  require 'leg/commands/repo'
12
14
  require 'leg/commands/undiff'
@@ -17,6 +17,9 @@ class Leg::Commands::BaseCommand
17
17
  true: "You are not in a leg working directory.",
18
18
  false: "You are already in a leg working directory."
19
19
  },
20
+ config_title: {
21
+ true: "You need to set a title in leg.yml."
22
+ },
20
23
  steps_folder: {
21
24
  true: "There is no steps folder.",
22
25
  false: "There is already a steps folder."
@@ -30,6 +33,9 @@ class Leg::Commands::BaseCommand
30
33
  },
31
34
  diff: {
32
35
  true: "There is no steps.diff file."
36
+ },
37
+ doc: {
38
+ true: "There is no doc folder."
33
39
  }
34
40
  }
35
41
 
@@ -45,6 +51,8 @@ class Leg::Commands::BaseCommand
45
51
  case what
46
52
  when :config
47
53
  valid = true if @config
54
+ when :config_title
55
+ valid = true if @config[:title]
48
56
  when :steps_folder
49
57
  valid = true if File.exist?(File.join(@config[:path], "steps"))
50
58
  when :steps
@@ -53,6 +61,8 @@ class Leg::Commands::BaseCommand
53
61
  valid = true if File.exist?(File.join(@config[:path], "repo"))
54
62
  when :diff
55
63
  valid = true if File.exist?(File.join(@config[:path], "steps.diff"))
64
+ when :doc
65
+ valid = true if File.exist?(File.join(@config[:path], "doc"))
56
66
  else
57
67
  raise NotImplementedError
58
68
  end
@@ -11,7 +11,7 @@ class Leg::Commands::Diff < Leg::Commands::BaseCommand
11
11
  needs! :config, :repo
12
12
 
13
13
  FileUtils.cd(File.join(@config[:path], "repo")) do
14
- patches = `git format-patch --stdout -p --no-signature --root master`
14
+ patches = `git format-patch --stdout -p --no-signature --histogram --root master`
15
15
  File.open("../steps.diff", "w") do |f|
16
16
  step_num = 1
17
17
  patches.each_line do |line|
@@ -0,0 +1,221 @@
1
+ class Leg::Commands::Doc < Leg::Commands::BaseCommand
2
+ def self.name
3
+ "doc"
4
+ end
5
+
6
+ def self.summary
7
+ "Renders files in doc folder into an HTML book"
8
+ end
9
+
10
+ def run
11
+ needs! :config, :config_title, :steps_folder, :steps, :doc
12
+
13
+ FileUtils.cd(File.join(@config[:path], "doc")) do
14
+ FileUtils.rm_rf("html_out")
15
+ FileUtils.mkdir("html_out")
16
+
17
+ copy_static_files
18
+ write_css
19
+ write_html_files(prerender_diffs)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def copy_static_files
26
+ Dir["html_in/*"].each do |f|
27
+ name = File.basename(f)
28
+ unless %w(template.html style.css).include? name
29
+ FileUtils.cp(f, "html_out/#{name}")
30
+ end
31
+ end
32
+ end
33
+
34
+ def write_css
35
+ @config[:rouge_theme] ||= "github"
36
+ if @config[:rouge_theme].is_a? String
37
+ theme = Rouge::Theme.find(@config[:rouge_theme])
38
+ elsif @config[:rouge_theme].is_a? Hash
39
+ theme = Class.new(Rouge::Themes::Base16)
40
+ theme.name "base16.custom"
41
+ theme.palette @config[:rouge_theme]
42
+ end
43
+
44
+ css = File.read("html_in/style.css")
45
+ css << theme.render(scope: ".highlight")
46
+
47
+ File.write("html_out/style.css", css)
48
+ end
49
+
50
+ def prerender_diffs
51
+ diffs = {}
52
+ FileUtils.cd("../steps") do
53
+ FileUtils.mkdir_p("0")
54
+
55
+ last_step = "0"
56
+ Dir["*"].sort_by(&:to_i).each do |step|
57
+ names = [step.to_i.to_s]
58
+ if step =~ /\d+\-([\w-]+)$/
59
+ names << $1
60
+ end
61
+
62
+ diffout = []
63
+ section_stack = []
64
+ in_diff = false
65
+ lexer = nil
66
+ formatter = Rouge::Formatters::HTML.new
67
+
68
+ diff = `git diff --histogram --unified=100000 --ignore-space-change --no-index #{last_step} #{step}`
69
+ diff.lines.each do |line|
70
+ if !in_diff && line =~ /^\+\+\+ (.+)$/
71
+ filename = File.basename($1)
72
+ lexer = Rouge::Lexer.guess(filename: filename)
73
+ diffout << {type: :section, section_type: :file, summary: filename, content: []}
74
+ section_stack = [diffout.last]
75
+ elsif line.start_with? '@@'
76
+ in_diff = true
77
+ elsif in_diff && [' ', '+', '-'].include?(line[0])
78
+ line_hl = formatter.format(lexer.lex(line[1..-1])).gsub("\n", "")
79
+ type = {' ' => :nochange, '+' => :add, '-' => :remove }[line[0]]
80
+
81
+ section_stack.each { |s| s[:dirty] = true } if type != :nochange
82
+
83
+ if line[1..-1] =~ /^\/\*\*\* (.+) \*\*\*\/$/
84
+ section_stack = [section_stack[0]]
85
+ section_stack.last[:content] << {type: :section, section_type: :comment, summary: line[1..-1].chomp, content: []}
86
+ section_stack.push(section_stack.last[:content].last)
87
+ elsif line[1] =~ /\S/ && line.chomp[-1] == "{"
88
+ section_stack.pop if section_stack.length > 1 && section_stack.last[:section_type] == :braces
89
+ section_stack.last[:content] << {type: :section, section_type: :braces, summary: line[1..-1].chomp + " ... ", content: []}
90
+ section_stack.push(section_stack.last[:content].last)
91
+ end
92
+
93
+ section_stack.last[:content] << {type: type, content: line_hl}
94
+
95
+ if line[1..-1] =~ /^(}( \w+)?;?)$/ && section_stack.last[:section_type] == :braces
96
+ s = section_stack.pop
97
+ s[:summary] << $1
98
+ end
99
+
100
+ section_stack.each { |s| s[:dirty] = true } if type != :nochange
101
+ else
102
+ in_diff = false
103
+ end
104
+ end
105
+
106
+ change_chain = []
107
+ diffout.each do |file|
108
+ to_render = file[:content].dup
109
+ until to_render.empty?
110
+ cur = to_render.shift
111
+ if cur[:type] == :section
112
+ if cur[:dirty]
113
+ to_render = cur[:content] + to_render
114
+ else
115
+ if change_chain.first && change_chain.first[:content].empty?
116
+ change_chain.first[:type] = :nochange
117
+ end
118
+ if change_chain.last && change_chain.last[:content].empty?
119
+ change_chain.last[:type] = :nochange
120
+ end
121
+ change_chain = []
122
+ end
123
+ else
124
+ if cur[:type] == :nochange
125
+ if change_chain.first && change_chain.first[:content].empty?
126
+ change_chain.first[:type] = :nochange
127
+ end
128
+ if change_chain.last && change_chain.last[:content].empty?
129
+ change_chain.last[:type] = :nochange
130
+ end
131
+ change_chain = []
132
+ else
133
+ change_chain << cur
134
+ if cur[:type] == :add
135
+ change_chain.each { |c| c[:omit] = true if c[:type] == :remove }
136
+ elsif cur[:type] == :remove
137
+ cur[:omit] = true if change_chain.any? { |c| c[:type] == :add }
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ html = ""
145
+ diffout.each do |file|
146
+ html << "<div class=\"diff\">\n"
147
+ html << "<div class=\"filename\">#{file[:summary]}</div>\n"
148
+ html << "<pre class=\"highlight\"><code>"
149
+
150
+ to_render = file[:content].dup
151
+ until to_render.empty?
152
+ cur = to_render.shift
153
+ if cur[:type] == :section
154
+ if cur[:dirty]
155
+ to_render = cur[:content] + to_render
156
+ else
157
+ summary = formatter.format(lexer.lex(cur[:summary])).gsub("\n", "")
158
+ html << "<div class=\"line folded\">#{summary}</div>"
159
+ end
160
+ elsif !cur[:omit]
161
+ tag = {nochange: :div, add: :ins, remove: :del}[cur[:type]]
162
+ html << "<#{tag} class=\"line\">#{cur[:content]}</#{tag}>"
163
+ end
164
+ end
165
+
166
+ html << "</code></pre>\n</div>\n"
167
+ end
168
+
169
+ names.each do |name|
170
+ diffs[name] = html
171
+ end
172
+
173
+ last_step = step
174
+ end
175
+
176
+ FileUtils.rmdir("0")
177
+ end
178
+
179
+ diffs
180
+ end
181
+
182
+ def write_html_files(diffs)
183
+ html_template = File.read("html_in/template.html")
184
+
185
+ index = ""
186
+ markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
187
+ Dir["*.md"].sort.each do |md_file|
188
+ html_file = md_file.sub(/\.md$/, '.html')
189
+
190
+ md = File.read(md_file)
191
+ md =~ /^# (.+)$/
192
+ title = $1
193
+
194
+ index << "<li><a href='#{html_file}'>#{title}</a></li>\n"
195
+
196
+ content = markdown.render(md)
197
+ content.gsub!(/<p>{{([\w-]+)}}<\/p>/) { diffs[$1] }
198
+
199
+ html = html_template.dup
200
+ html.gsub!("{{title}}") { "#{@config[:title]} | #{title}" }
201
+ html.gsub!("{{content}}") { content }
202
+
203
+ File.write(File.join("html_out", html_file), html)
204
+ end
205
+
206
+ content = <<~HTML
207
+ <h1>#{@config[:title]}</h1>
208
+ <h2>Table of Contents</h2>
209
+ <ol>
210
+ #{index}
211
+ </ol>
212
+ HTML
213
+
214
+ html = html_template.dup
215
+ html.gsub!("{{title}}", @config[:title])
216
+ html.gsub!("{{content}}", content)
217
+
218
+ File.write("html_out/index.html", html)
219
+ end
220
+ end
221
+
@@ -0,0 +1,26 @@
1
+ class Leg::Commands::Fancy < Leg::Commands::BaseCommand
2
+ def self.name
3
+ "fancy"
4
+ end
5
+
6
+ def self.summary
7
+ "Run steps.diff through colordiff, diff-so-fancy, and less"
8
+ end
9
+
10
+ def run
11
+ needs! :config, :diff
12
+
13
+ FileUtils.cd(@config[:path]) do
14
+ exec("cat steps.diff | colordiff | diff-so-fancy | less --tabs=4 -RFX")
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def apply_diff(dir, diff)
21
+ stdin = IO.popen("git --git-dir= apply --directory=#{dir} -", "w")
22
+ stdin.write diff
23
+ stdin.close
24
+ end
25
+ end
26
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oleg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Ruten
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-09 00:00:00.000000000 Z
11
+ date: 2017-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rugged
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.25.1.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: redcarpet
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 3.4.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 3.4.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rouge
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 2.0.7
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.0.7
27
55
  description:
28
56
  email: jeremy.ruten@gmail.com
29
57
  executables:
@@ -37,6 +65,8 @@ files:
37
65
  - lib/leg/commands.rb
38
66
  - lib/leg/commands/base_command.rb
39
67
  - lib/leg/commands/diff.rb
68
+ - lib/leg/commands/doc.rb
69
+ - lib/leg/commands/fancy.rb
40
70
  - lib/leg/commands/help.rb
41
71
  - lib/leg/commands/pieces.rb
42
72
  - lib/leg/commands/ref.rb