oleg 0.6.0 → 0.7.0

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.
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