bhook 0.1.1 → 0.1.4

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
  SHA256:
3
- metadata.gz: 9a429bac22b3cc378e763dabbad48a1b22263160b1ce2e84a8e476f69c2f0783
4
- data.tar.gz: bebc1d4b7ae5e570e29a8075505d8a326adc16af6abc6d62113e1cb21db4c14f
3
+ metadata.gz: 5ffd9eb1c5db23eb8abdd4a3fab6932720c3774697c27656ecf4ddcae1732eeb
4
+ data.tar.gz: cf87062c2146ca04a7dc3e64e85909a8dd5d53799e6f6cea8aeccf2d197701e3
5
5
  SHA512:
6
- metadata.gz: 9bbffd373a9b185635617be72154d16f358fad87b6592b1e9bb23e9295eb7a682f229dc004bcf43f1fef02e5e9838b0b15475343b2040a94b78803cbd6844e61
7
- data.tar.gz: 2033c32dc2107c52197a6b71581970324cf0e05164948b5c83cdbf80bf0bc7665b8d3f89372e432344b6d0e23728a4b5b68a8c0bb6df40dcb079b47c6f8121a4
6
+ metadata.gz: d2071d0b4baf4b58dd94ec675323f416bc4864f964506e79c04db3618a4338c44f7d151aff1137467f174c07df06ce26bc2cbf2d13b0f66476b6f47ef960305f
7
+ data.tar.gz: 3e3693defc38e9e1598c1cca637c48fbc305bfb012602d4b458f916c024f9260de650863ed25a4ba15737a4933fc4e5b037a75b70f7fcd70559e561cdb285752
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bhook (0.1.1)
4
+ bhook (0.1.4)
5
5
  git (~> 1.10)
6
6
  kramdown (~> 2.3)
7
7
  listen (~> 3.7)
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Bhook
2
2
 
3
- Bhook is a static website generator that works off a git repo containing a markdown file based wiki.
3
+ Bhook is a static website generator that works off a git repo containing a markdown file based wiki, like for example, the [India Startup Wiki](https://gitlab.com/india-startups/wiki).
4
+
5
+ I use this to create [HTML versions of the wiki](https://sidu.in/wiki/startups) and of [my essays](https://sidu.in/essays/) that I can publish.
4
6
 
5
7
  ## Installation
6
8
 
@@ -13,17 +15,21 @@ Install it yourself as:
13
15
  Getting help:
14
16
 
15
17
  $ bhook --help
16
- Bhook version 0.1.0
18
+ Bhook version 0.1.4
17
19
  Usage: bhook --source /source/path --output /output/path
18
20
  -s, --source=SOURCE Path to version controlled directory containing source md files
19
21
  -o, --output=OUTPUT Path to directory where output files are to be generated
20
22
  -w, --watch Continuously watch the source directory for changes and generate output
21
- -t, --typechecking Enables sorbet runtime typechecking. Only useful when developing bhook.
23
+ -v, --verbose Print detailed information about files as they are processed
24
+ -t, --theme=PATH Path to directory containing theme files to use when generating html
25
+ --generate-theme=PATH Generate a baseline theme that you can then modify to your needs
26
+ --benchmark Run a performance benchmark for the specified source
22
27
  -h, --help Prints this help
23
28
 
24
29
  How I use it:
25
30
 
26
- ➜ essays git:(main) ✗ bhook -s . -o /tmp/out -w
31
+ ➜ essays git:(main) ✗ bhook -s . -o /tmp/out -t /tmp/out/theme -w -v
32
+
27
33
  ## Development
28
34
 
29
35
  1. `git clone --recursive git@gitlab.com:kaiwren/bhook.git`
data/bin/bhook CHANGED
@@ -7,10 +7,27 @@ require 'bhook'
7
7
  puts "Bhook version #{Bhook::VERSION}"
8
8
  args = Bhook::ArgsParser.new(ARGV).parse
9
9
 
10
+ if args.verbose
11
+ Bhook::L.level = Logger::DEBUG
12
+ else
13
+ Bhook::L.level = Logger::INFO
14
+ end
15
+
10
16
  if args.generate_theme
11
17
  Bhook::ThemeGenerator.new(args.generate_theme).generate!
12
18
  exit
13
19
  end
14
20
 
15
21
  workspace = Bhook::Workspace.new(args.source, args.output, args.theme)
22
+
23
+ if args.benchmark
24
+ require 'benchmark'
25
+ n = 10
26
+ Benchmark.bmbm do |bench|
27
+ Bhook::L.level = Logger::WARN
28
+ bench.report("Generate HTML #{n} times") { n.times { workspace.process! } }
29
+ end
30
+ exit
31
+ end
32
+
16
33
  args.watch ? workspace.watch! : workspace.process!
@@ -1,9 +1,14 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
1
4
  module Bhook
2
5
  class ArgsParser
3
- Options = Struct.new(:source, :output, :watch, :typechecking, :theme, :generate_theme)
6
+ extend T::Sig
7
+
8
+ Options = Struct.new(:source, :output, :watch, :verbose, :theme, :generate_theme, :benchmark)
4
9
 
5
10
  def initialize(argv)
6
- @args = Options.new(nil, nil, false, false, nil, nil)
11
+ @args = Options.new(nil, nil, false, false, Bhook::THEME_DIR_PATH, nil, false)
7
12
  @argv = argv.clone
8
13
  @opt_parser = build_opt_parser
9
14
  end
@@ -56,6 +61,12 @@ module Bhook
56
61
  @args.watch = true
57
62
  end
58
63
 
64
+ opts.on("-v", "--verbose",
65
+ FalseClass,
66
+ "Print detailed information about files as they are processed") do
67
+ @args.verbose = true
68
+ end
69
+
59
70
  opts.on("-tPATH", "--theme=PATH",
60
71
  String,
61
72
  "Path to directory containing theme files to use when generating html") do |path|
@@ -68,6 +79,12 @@ module Bhook
68
79
  @args.generate_theme = path
69
80
  end
70
81
 
82
+ opts.on("--benchmark",
83
+ FalseClass,
84
+ "Run a performance benchmark for the specified source") do
85
+ @args.benchmark = true
86
+ end
87
+
71
88
  opts.on("-h", "--help", "Prints this help") do
72
89
  puts opts
73
90
  exit
@@ -0,0 +1,30 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Bhook
5
+ class Config
6
+ extend T::Sig
7
+ BHOOK_CONFIG_FILE = T.let('.bhook', String)
8
+ WEBSITE_KEY = T.let('website', String)
9
+
10
+ sig { params(root_dir_path: Pathname).void }
11
+ def initialize(root_dir_path)
12
+ config_file_path = root_dir_path.join(BHOOK_CONFIG_FILE)
13
+ config = if File.exist?(config_file_path)
14
+ YAML.load(File.read(config_file_path))
15
+ else
16
+ {}
17
+ end
18
+ @root_dir_path = root_dir_path
19
+ @website_url = T.let(config[WEBSITE_KEY], T.nilable(String))
20
+ end
21
+
22
+ sig { params(src_file_path: Pathname, src_file_sha: T.nilable(String)).returns(T.nilable(String)) }
23
+ def website_url_for(src_file_path, src_file_sha)
24
+ if @website_url && src_file_sha
25
+ relative_file_path = src_file_path.relative_path_from(@root_dir_path)
26
+ URI::join(@website_url, "#{src_file_sha}/#{relative_file_path}").to_s
27
+ end
28
+ end
29
+ end
30
+ end
@@ -16,7 +16,7 @@ module Bhook
16
16
  def convert_a(el, indent)
17
17
  href_path = el.attr['href']
18
18
  if valid_relative_md_link?(href_path)
19
- puts "Found link: #{href_path}"
19
+ L.debug "Found link: #{href_path}"
20
20
  el.attr['href'].gsub!(/\.md/, '.html')
21
21
  end
22
22
  super(el, indent)
@@ -8,31 +8,33 @@ module Bhook
8
8
  GIT_DIR = '.git'
9
9
  MD_EXT = '.md'
10
10
 
11
- sig { params(src_path: Pathname, git: T.nilable(Git::Base)).void }
12
- def initialize(src_path, git = nil)
11
+ sig { params(src_path: Pathname, out_path: Pathname).returns(Bhook::Directory) }
12
+ def self.new_root_directory(src_path, out_path)
13
+ self.new(src_path, out_path, Git.open(src_path), Bhook::Config.new(src_path))
14
+ end
15
+
16
+
17
+ sig { params(src_path: Pathname, out_path: Pathname, git: Git::Base, config: Bhook::Config).void }
18
+ def initialize(src_path, out_path, git, config)
13
19
  @src_path = src_path
20
+ @out_path = T.let(out_path.join(src_path.basename), Pathname)
14
21
  @git = git
22
+ @config = config
15
23
  @sub_dirs = T.let([], T::Array[Directory])
16
24
  @md_files = T.let([], T::Array[MdFile])
17
25
  build_next_level_nodes
18
26
  end
19
27
 
20
- sig { returns(T::Boolean) }
21
- def root_dir_for_a_commit?
22
- !@git
23
- end
24
-
25
- sig { params(out_path: String, theme: Theme).void }
26
- def write!(out_path, theme)
27
- dir_path = if root_dir_for_a_commit?
28
- out_path
29
- else
30
- File.join(out_path, @src_path.basename)
31
- end
32
-
33
- FileUtils.mkdir_p(dir_path, verbose: true)
34
- @sub_dirs.each { |dir| dir.write!(dir_path, theme) }
35
- @md_files.each { |file| file.write!(dir_path, theme) }
28
+ sig { params(theme: Theme).void }
29
+ def write!(theme)
30
+ FileUtils.mkdir_p(@out_path)
31
+ L.debug("mkdir: #{@out_path}")
32
+ @sub_dirs.each { |dir| dir.write!(theme) }
33
+ @md_files.map do |file|
34
+ Thread.new { file.write!(theme) }
35
+ end.each do |thread|
36
+ thread.join
37
+ end
36
38
  end
37
39
 
38
40
  sig { returns(T::Array[MdFile]) }
@@ -44,25 +46,23 @@ module Bhook
44
46
  def to_s
45
47
  @src_path.to_s
46
48
  end
47
-
49
+
48
50
  private
49
51
 
50
52
  sig { void }
51
53
  def build_next_level_nodes
52
- if root_dir_for_a_commit?
53
- @git = Git.open(@src_path)
54
- end
55
-
56
- @sub_dirs = @src_path.children.map do |child|
57
- if child.directory? && child.basename.to_s != GIT_DIR
58
- Directory.new(child, @git)
54
+ children = @src_path.children
55
+ children.delete(@src_path.join(GIT_DIR))
56
+
57
+ file_threads = []
58
+ children.each do |child_path|
59
+ if child_path.directory?
60
+ @sub_dirs << Directory.new(child_path, @out_path, @git, @config)
61
+ elsif child_path.extname == MD_EXT
62
+ file_threads << Thread.new { MdFile.new(child_path, @out_path, @git, @config) }
59
63
  end
60
- end.compact
61
- @md_files = @src_path.children.select do |child|
62
- !child.directory? && child.extname == MD_EXT
63
- end.map do |child|
64
- MdFile.new(child, @git)
65
- end.compact
64
+ end
65
+ file_threads.each { |thread| @md_files << thread.value }
66
66
  end
67
67
  end
68
68
  end
@@ -0,0 +1,8 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module Bhook
5
+ L = Logger.new(STDOUT, formatter: proc {|severity, datetime, progname, msg|
6
+ "#{Thread.current.object_id} #{msg}\n"
7
+ })
8
+ end
data/lib/bhook/md_file.rb CHANGED
@@ -8,30 +8,32 @@ module Bhook
8
8
  PAGE_TEMPLATE = T.let(File.read(Bhook::PAGE_TEMPLATE_PATH), String)
9
9
  AFTER_H1_TEMPLATE = T.let(File.read(Bhook::AFTER_H1_TEMPLATE_PATH), String)
10
10
 
11
- sig { params(src_file_path: Pathname, git: Git::Base).void }
12
- def initialize(src_file_path, git)
11
+ sig { returns(Pathname) }
12
+ attr_reader :src_file_path
13
+
14
+ sig { params(src_file_path: Pathname, out_path: Pathname, git: Git::Base, config: Bhook::Config).void }
15
+ def initialize(src_file_path, out_path, git, config)
16
+ L.debug "Reading: #{src_file_path}"
13
17
  @md = T.let(File.read(src_file_path), String)
14
- @src_file_path = T.let(src_file_path.expand_path, Pathname)
15
- src_file_date, src_file_sha = git.lib.send(:command, 'log',
16
- '-n 1',
17
- '--pretty=format:%ad|%h',
18
- '--date=short',
19
- '--',
20
- @src_file_path).split('|')
18
+ @src_file_path = src_file_path
19
+ @out_path = out_path
20
+ @git = git
21
+ @config = config
22
+ src_file_date, src_file_sha = load_git_file_metadata
21
23
  @src_file_date = T.let(src_file_date, T.nilable(String))
22
24
  @src_file_sha = T.let(src_file_sha, T.nilable(String))
23
25
  end
24
26
 
25
- sig { returns(Pathname) }
26
- attr_reader :src_file_path
27
+ sig { params(theme: Bhook::Theme).void }
28
+ def write!(theme)
29
+ out_file_name = @src_file_path.basename.sub(/\.md$/, '.html')
30
+ out_file_path = @out_path.join(out_file_name)
31
+ file_url = @config.website_url_for(@src_file_path, @src_file_sha)
27
32
 
28
- sig { params(out_path: String, theme: Bhook::Theme).void }
29
- def write!(out_path, theme)
30
- out_file_name = File.basename(@src_file_path).gsub(/\.md$/, '.html')
31
- out_file_path = File.join(out_path, out_file_name)
32
- puts "Processing: #{@src_file_sha} #{@src_file_path}"
33
- rendered_page = theme.render_page(@md, @src_file_sha, @src_file_date)
34
- puts "Writing: #{@src_file_sha} #{out_file_path}"
33
+ L.debug "Processing: #{@src_file_sha || 'unversioned'} #{@src_file_path}"
34
+ rendered_page = theme.render_page(@md, @src_file_sha, @src_file_date, file_url)
35
+
36
+ L.debug "Writing: #{@src_file_sha} #{out_file_path}"
35
37
  File.write(out_file_path, rendered_page)
36
38
  end
37
39
 
@@ -39,5 +41,17 @@ module Bhook
39
41
  def to_s
40
42
  @src_file_path.to_s
41
43
  end
44
+
45
+ private
46
+
47
+ sig { returns(T::Array[String]) }
48
+ def load_git_file_metadata
49
+ @git.lib.send(:command, 'log',
50
+ '-n 1',
51
+ '--pretty=format:%ad|%H',
52
+ '--date=short',
53
+ '--',
54
+ @src_file_path).split('|')
55
+ end
42
56
  end
43
57
  end
@@ -40,6 +40,13 @@
40
40
  padding: 0.1em 1em 0.1em 1em;
41
41
  border: 1px solid #bbbbbb;
42
42
  }
43
+
44
+ blockquote {
45
+ border-left: 10px solid #cccccc;
46
+ background: #eeeeee;
47
+ display: inline-block;
48
+ padding: 1em;
49
+ }
43
50
  </style>
44
51
  <title><%= src_title -%></title>
45
52
  </head>
@@ -52,7 +59,13 @@
52
59
  </div>
53
60
  <div class="footer d-flex justify-content-center">
54
61
  <div>
55
- v. <%= src_file_sha -%>, <%= src_file_date -%> © <a href="https://sidu.in">Sidu Ponnappa</a>
62
+ <% short_sha = src_file_sha ? src_file_sha[0..7] : nil -%>
63
+ <% if file_url && short_sha -%>
64
+ v. <a href="<%= file_url -%>"><%= short_sha -%></a>,
65
+ <% elsif short_sha -%>
66
+ v. <%= short_sha -%>,
67
+ <% end -%>
68
+ <%= src_file_date -%> © <a href="https://sidu.in">Sidu Ponnappa</a>
56
69
  </div>
57
70
  </div>
58
71
  </div>
data/lib/bhook/theme.rb CHANGED
@@ -13,8 +13,9 @@ module Bhook
13
13
  @after_h1_strategy = T.let(strategy, T.proc.params(binding_instance: Binding).returns(String))
14
14
  end
15
15
 
16
- sig { params(md: String, src_file_sha: T.nilable(String), src_file_date: T.nilable(String)).returns(String) }
17
- def render_page(md, src_file_sha, src_file_date)
16
+ sig { params(md: String, src_file_sha: T.nilable(String),
17
+ src_file_date: T.nilable(String), file_url: T.nilable(String)).returns(String) }
18
+ def render_page(md, src_file_sha, src_file_date, file_url)
18
19
  src_title = T.let('', String)
19
20
 
20
21
  doc = Kramdown::Document.new(md)
data/lib/bhook/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Bhook
5
- VERSION = '0.1.1'
5
+ VERSION = '0.1.4'
6
6
  end
@@ -4,28 +4,28 @@
4
4
  module Bhook
5
5
  class Workspace
6
6
  extend T::Sig
7
-
7
+
8
8
  sig { params(src_path: String, out_path: String, theme_path: String).void }
9
9
  def initialize(src_path, out_path, theme_path)
10
- @src_path = src_path
11
- @out_path = out_path
10
+ @src_path = T.let(Pathname.new(src_path).expand_path, Pathname)
11
+ @out_path = T.let(Pathname.new(out_path).expand_path, Pathname)
12
12
  @theme = T.let(Theme.new(theme_path), Bhook::Theme)
13
13
  end
14
14
 
15
15
  sig { void }
16
- def process!
17
- root = root_dir
18
- root.write!(@out_path, @theme)
16
+ def process!
17
+ root_dir.write!(@theme)
18
+ L.info "Done!"
19
19
  end
20
20
 
21
21
  sig { void }
22
22
  def watch!
23
23
  process!
24
- puts
25
- puts "Watching #{@src_path} for changes..."
26
- listener = Listen.to(@src_path, File.join(@src_path, '.git')) do |_modified, _added, _removed|
24
+
25
+ L.info "Watching: #{@src_path} for changes..."
26
+ listener = Listen.to(@src_path.to_s, File.join(@src_path.to_s, '.git')) do |_modified, _added, _removed|
27
+ L.info "Detected changes..."
27
28
  process!
28
- puts "-----\n"
29
29
  end
30
30
  listener.start
31
31
  sleep
@@ -35,12 +35,11 @@ module Bhook
35
35
  def all_md_files
36
36
  root_dir.all_md_files
37
37
  end
38
-
39
- private
40
-
38
+
39
+ private
41
40
  sig { returns(Bhook::Directory) }
42
41
  def root_dir
43
- Directory.new(Pathname.new(@src_path))
42
+ Directory.new_root_directory(@src_path, @out_path)
44
43
  end
45
44
  end
46
45
  end
data/lib/bhook.rb CHANGED
@@ -6,6 +6,9 @@ require 'fileutils'
6
6
  require 'pathname'
7
7
  require 'erb'
8
8
  require 'optparse'
9
+ require 'logger'
10
+ require 'uri'
11
+ require 'yaml'
9
12
  require 'sorbet-runtime'
10
13
  require 'git'
11
14
  require 'kramdown'
@@ -22,7 +25,9 @@ module Bhook
22
25
  end
23
26
 
24
27
  require_relative 'bhook/version'
28
+ require_relative 'bhook/logger'
25
29
  require_relative 'bhook/args_parser'
30
+ require_relative 'bhook/config'
26
31
  require_relative 'bhook/theme_generator'
27
32
  require_relative 'bhook/theme'
28
33
  require_relative 'bhook/converter/html'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bhook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sidu Ponnappa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-13 00:00:00.000000000 Z
11
+ date: 2022-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: git
@@ -169,8 +169,10 @@ files:
169
169
  - bin/bhook
170
170
  - lib/bhook.rb
171
171
  - lib/bhook/args_parser.rb
172
+ - lib/bhook/config.rb
172
173
  - lib/bhook/converter/html.rb
173
174
  - lib/bhook/directory.rb
175
+ - lib/bhook/logger.rb
174
176
  - lib/bhook/md_file.rb
175
177
  - lib/bhook/theme.rb
176
178
  - lib/bhook/theme/_after_h1.erb