bhook 0.1.1 → 0.1.4

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