bhook 0.1.4 → 0.2.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 +4 -4
- data/.rubocop.yml +33 -1
- data/Gemfile.lock +29 -17
- data/README.md +10 -1
- data/Rakefile +22 -1
- data/bin/bhook +11 -6
- data/lib/bhook/args_parser.rb +47 -44
- data/lib/bhook/config.rb +43 -14
- data/lib/bhook/converter/html.rb +2 -4
- data/lib/bhook/directory.rb +14 -13
- data/lib/bhook/logger.rb +4 -3
- data/lib/bhook/md_file.rb +33 -19
- data/lib/bhook/theme/page.erb +10 -12
- data/lib/bhook/theme.rb +4 -2
- data/lib/bhook/theme_generator.rb +7 -5
- data/lib/bhook/version.rb +1 -1
- data/lib/bhook/workspace.rb +7 -6
- data/sorbet/rbi/gems/bhook.rbi +2 -1
- data/sorbet/rbi/gems/docile.rbi +36 -0
- data/sorbet/rbi/gems/git.rbi +1 -1
- data/sorbet/rbi/gems/kramdown.rbi +1 -1
- data/sorbet/rbi/gems/parallel.rbi +4 -1
- data/sorbet/rbi/gems/parser.rbi +1 -1
- data/sorbet/rbi/gems/regexp_parser.rbi +138 -120
- data/sorbet/rbi/gems/rspec-mocks.rbi +1 -1
- data/sorbet/rbi/gems/rubocop-ast.rbi +1 -1
- data/sorbet/rbi/gems/rubocop-rspec.rbi +35 -9
- data/sorbet/rbi/gems/rubocop.rbi +268 -40
- data/sorbet/rbi/gems/simplecov-cobertura.rbi +30 -0
- data/sorbet/rbi/gems/simplecov-html.rbi +35 -0
- data/sorbet/rbi/gems/simplecov.rbi +419 -0
- data/sorbet/rbi/gems/simplecov_json_formatter.rbi +47 -0
- data/sorbet/rbi/hidden-definitions/errors.txt +81 -68
- data/sorbet/rbi/hidden-definitions/hidden.rbi +186 -27
- metadata +36 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8daa36a6bba5cff236d6bf93f33ff088d7baa4abb975fe372674c94746e3600
|
4
|
+
data.tar.gz: 499905877d932384d7cb982290ed6bfced51398b63a85ef3101a625783f2113b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7538dd31e1790aab7fabca99e652ff97752c52bd0afeb7ade8d42d517eee6bd2f6687e642c06b95afe4e51cc48724b84646f6f9ee5803d3a73ae9b23f64023e
|
7
|
+
data.tar.gz: 1d5aa665979f1be6f1ba0a96d7068622c782e604a1407a0757e6d254f538dde59507972e15412fcb7141d38f430ff0897c9e95ca8b3a6227b727f575d32bfb36
|
data/.rubocop.yml
CHANGED
@@ -1,3 +1,35 @@
|
|
1
1
|
require:
|
2
2
|
- rubocop-rake
|
3
|
-
- rubocop-rspec
|
3
|
+
- rubocop-rspec
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
NewCops: enable
|
7
|
+
|
8
|
+
Style/AccessorGrouping:
|
9
|
+
Enabled: false
|
10
|
+
|
11
|
+
Style/Documentation:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Naming/MethodParameterName:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
RSpec/MessageSpies:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
RSpec/MultipleExpectations:
|
21
|
+
Exclude:
|
22
|
+
- spec/bhook/theme_generator_spec.rb
|
23
|
+
|
24
|
+
Metrics/MethodLength:
|
25
|
+
Exclude:
|
26
|
+
- lib/bhook/args_parser.rb
|
27
|
+
|
28
|
+
Metrics/BlockLength:
|
29
|
+
Exclude:
|
30
|
+
- lib/bhook/args_parser.rb
|
31
|
+
|
32
|
+
Metrics/AbcSize:
|
33
|
+
Exclude:
|
34
|
+
- lib/bhook/args_parser.rb
|
35
|
+
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bhook (0.
|
4
|
+
bhook (0.2.0)
|
5
5
|
git (~> 1.10)
|
6
6
|
kramdown (~> 2.3)
|
7
7
|
listen (~> 3.7)
|
@@ -12,16 +12,17 @@ GEM
|
|
12
12
|
specs:
|
13
13
|
ast (2.4.2)
|
14
14
|
diff-lcs (1.5.0)
|
15
|
+
docile (1.4.0)
|
15
16
|
ffi (1.15.5)
|
16
|
-
git (1.
|
17
|
+
git (1.11.0)
|
17
18
|
rchardet (~> 1.8)
|
18
|
-
kramdown (2.
|
19
|
+
kramdown (2.4.0)
|
19
20
|
rexml
|
20
21
|
listen (3.7.1)
|
21
22
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
22
23
|
rb-inotify (~> 0.9, >= 0.9.10)
|
23
|
-
parallel (1.
|
24
|
-
parser (3.1.
|
24
|
+
parallel (1.22.1)
|
25
|
+
parser (3.1.2.0)
|
25
26
|
ast (~> 2.4.1)
|
26
27
|
rainbow (3.1.1)
|
27
28
|
rake (13.0.6)
|
@@ -29,7 +30,7 @@ GEM
|
|
29
30
|
rb-inotify (0.10.1)
|
30
31
|
ffi (~> 1.0)
|
31
32
|
rchardet (1.8.0)
|
32
|
-
regexp_parser (2.
|
33
|
+
regexp_parser (2.5.0)
|
33
34
|
rexml (3.2.5)
|
34
35
|
rspec (3.11.0)
|
35
36
|
rspec-core (~> 3.11.0)
|
@@ -40,30 +41,39 @@ GEM
|
|
40
41
|
rspec-expectations (3.11.0)
|
41
42
|
diff-lcs (>= 1.2.0, < 2.0)
|
42
43
|
rspec-support (~> 3.11.0)
|
43
|
-
rspec-mocks (3.11.
|
44
|
+
rspec-mocks (3.11.1)
|
44
45
|
diff-lcs (>= 1.2.0, < 2.0)
|
45
46
|
rspec-support (~> 3.11.0)
|
46
47
|
rspec-support (3.11.0)
|
47
|
-
rubocop (1.
|
48
|
+
rubocop (1.30.0)
|
48
49
|
parallel (~> 1.10)
|
49
50
|
parser (>= 3.1.0.0)
|
50
51
|
rainbow (>= 2.2.2, < 4.0)
|
51
52
|
regexp_parser (>= 1.8, < 3.0)
|
52
|
-
rexml
|
53
|
-
rubocop-ast (>= 1.
|
53
|
+
rexml (>= 3.2.5, < 4.0)
|
54
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
54
55
|
ruby-progressbar (~> 1.7)
|
55
56
|
unicode-display_width (>= 1.4.0, < 3.0)
|
56
|
-
rubocop-ast (1.
|
57
|
-
parser (>= 3.
|
57
|
+
rubocop-ast (1.18.0)
|
58
|
+
parser (>= 3.1.1.0)
|
58
59
|
rubocop-rake (0.6.0)
|
59
60
|
rubocop (~> 1.0)
|
60
|
-
rubocop-rspec (2.
|
61
|
+
rubocop-rspec (2.11.1)
|
61
62
|
rubocop (~> 1.19)
|
62
63
|
ruby-progressbar (1.11.0)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
simplecov (0.21.2)
|
65
|
+
docile (~> 1.1)
|
66
|
+
simplecov-html (~> 0.11)
|
67
|
+
simplecov_json_formatter (~> 0.1)
|
68
|
+
simplecov-cobertura (2.1.0)
|
69
|
+
rexml
|
70
|
+
simplecov (~> 0.19)
|
71
|
+
simplecov-html (0.12.3)
|
72
|
+
simplecov_json_formatter (0.1.4)
|
73
|
+
sorbet (0.5.10042)
|
74
|
+
sorbet-static (= 0.5.10042)
|
75
|
+
sorbet-runtime (0.5.10042)
|
76
|
+
sorbet-static (0.5.10042-universal-darwin-21)
|
67
77
|
unicode-display_width (2.1.0)
|
68
78
|
|
69
79
|
PLATFORMS
|
@@ -76,6 +86,8 @@ DEPENDENCIES
|
|
76
86
|
rubocop (~> 1.0)
|
77
87
|
rubocop-rake (~> 0.6)
|
78
88
|
rubocop-rspec (~> 2.8)
|
89
|
+
simplecov (~> 0.21)
|
90
|
+
simplecov-cobertura (~> 2.1.0)
|
79
91
|
sorbet (~> 0.5)
|
80
92
|
|
81
93
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# Bhook
|
2
2
|
|
3
|
+
[](https://gitlab.com/kaiwren/bhook/commits/main)
|
4
|
+
[](https://gitlab.com/kaiwren/bhook/commits/main)
|
5
|
+
[](https://rubygems.org/gems/bhook)
|
6
|
+
[](https://rubygems.org/gems/bhook)
|
7
|
+
|
8
|
+
|
9
|
+
|
3
10
|
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
11
|
|
5
12
|
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.
|
@@ -15,7 +22,7 @@ Install it yourself as:
|
|
15
22
|
Getting help:
|
16
23
|
|
17
24
|
$ bhook --help
|
18
|
-
Bhook version 0.
|
25
|
+
Bhook version 0.2.0
|
19
26
|
Usage: bhook --source /source/path --output /output/path
|
20
27
|
-s, --source=SOURCE Path to version controlled directory containing source md files
|
21
28
|
-o, --output=OUTPUT Path to directory where output files are to be generated
|
@@ -30,6 +37,8 @@ How I use it:
|
|
30
37
|
|
31
38
|
➜ essays git:(main) ✗ bhook -s . -o /tmp/out -t /tmp/out/theme -w -v
|
32
39
|
|
40
|
+
Here's an example `.bhook.yml` [config file](https://gitlab.com/india-startups/wiki/-/blob/master/.bhook.yml).
|
41
|
+
|
33
42
|
## Development
|
34
43
|
|
35
44
|
1. `git clone --recursive git@gitlab.com:kaiwren/bhook.git`
|
data/Rakefile
CHANGED
@@ -2,7 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'bundler/gem_tasks'
|
4
4
|
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop/rake_task'
|
5
6
|
|
7
|
+
RuboCop::RakeTask.new
|
6
8
|
RSpec::Core::RakeTask.new(:spec)
|
7
9
|
|
8
10
|
desc 'Run Sorbet Typechecker'
|
@@ -10,4 +12,23 @@ task :sorbet do
|
|
10
12
|
sh('bundle exec srb tc')
|
11
13
|
end
|
12
14
|
|
13
|
-
|
15
|
+
basic_style_cops = %w[
|
16
|
+
Layout/TrailingWhitespace
|
17
|
+
Layout/SpaceInsideBlockBraces
|
18
|
+
Style/StringLiterals
|
19
|
+
]
|
20
|
+
|
21
|
+
desc "Apply #{basic_style_cops.join(', ')}"
|
22
|
+
task :autocorrect_basic_style_issues do
|
23
|
+
sh("bundle exec rubocop -a --only #{basic_style_cops.join(',')}")
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :ci do
|
27
|
+
desc 'Tasks to run in Gitlab CI build stage'
|
28
|
+
task build: %i[sorbet rubocop]
|
29
|
+
|
30
|
+
desc 'Tasks to run in Gitlab CI spec stage'
|
31
|
+
task spec: %i[spec]
|
32
|
+
end
|
33
|
+
|
34
|
+
task default: %i[autocorrect_basic_style_issues rubocop sorbet spec]
|
data/bin/bhook
CHANGED
@@ -5,18 +5,23 @@ require 'bundler/setup'
|
|
5
5
|
require 'bhook'
|
6
6
|
|
7
7
|
puts "Bhook version #{Bhook::VERSION}"
|
8
|
-
|
8
|
+
parser = Bhook::ArgsParser.new(ARGV)
|
9
|
+
args = parser.parse
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
exit unless args
|
12
|
+
|
13
|
+
if args.help
|
14
|
+
puts parser.help_text
|
15
|
+
exit
|
14
16
|
end
|
15
17
|
|
16
18
|
if args.generate_theme
|
19
|
+
Bhook::L.level = Logger::DEBUG
|
17
20
|
Bhook::ThemeGenerator.new(args.generate_theme).generate!
|
18
21
|
exit
|
19
|
-
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Bhook::L.level = args.verbose ? Logger::DEBUG : Logger::INFO
|
20
25
|
|
21
26
|
workspace = Bhook::Workspace.new(args.source, args.output, args.theme)
|
22
27
|
|
data/lib/bhook/args_parser.rb
CHANGED
@@ -1,95 +1,98 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module Bhook
|
5
5
|
class ArgsParser
|
6
6
|
extend T::Sig
|
7
|
-
|
8
|
-
Options = Struct.new(:source, :output, :watch, :verbose, :theme, :generate_theme, :benchmark)
|
9
|
-
|
7
|
+
|
8
|
+
Options = Struct.new(:source, :output, :watch, :verbose, :theme, :generate_theme, :benchmark, :help)
|
9
|
+
|
10
10
|
def initialize(argv)
|
11
|
-
@args = Options.new(nil, nil, false, false, Bhook::THEME_DIR_PATH, nil, false)
|
11
|
+
@args = Options.new(nil, nil, false, false, Bhook::THEME_DIR_PATH, nil, false, false)
|
12
12
|
@argv = argv.clone
|
13
13
|
@opt_parser = build_opt_parser
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def parse
|
17
17
|
begin
|
18
18
|
@opt_parser.parse(@argv)
|
19
|
+
if generate_theme_missing? && help_missing? && source_or_output_paths_missing?
|
20
|
+
raise OptionParser::MissingArgument, 'See --help.'
|
21
|
+
end
|
19
22
|
rescue OptionParser::ParseError => e
|
20
|
-
puts
|
21
|
-
|
22
|
-
puts
|
23
|
-
puts @opt_parser
|
24
|
-
exit
|
25
|
-
end
|
26
|
-
|
27
|
-
if source_or_output_paths_missing? && generate_theme_missing?
|
28
|
-
puts @opt_parser
|
29
|
-
exit
|
23
|
+
puts "\nError! #{e.message}\n"
|
24
|
+
return nil
|
30
25
|
end
|
26
|
+
|
31
27
|
@args
|
32
28
|
end
|
33
|
-
|
29
|
+
|
30
|
+
def help_text
|
31
|
+
@opt_parser.to_s
|
32
|
+
end
|
33
|
+
|
34
34
|
private
|
35
|
-
|
35
|
+
|
36
|
+
def help_missing?
|
37
|
+
!@args.help
|
38
|
+
end
|
39
|
+
|
36
40
|
def source_or_output_paths_missing?
|
37
41
|
!@args.source || !@args.output
|
38
42
|
end
|
39
|
-
|
43
|
+
|
40
44
|
def generate_theme_missing?
|
41
45
|
!@args.generate_theme
|
42
46
|
end
|
43
|
-
|
44
|
-
def build_opt_parser
|
47
|
+
|
48
|
+
def build_opt_parser
|
45
49
|
OptionParser.new do |opts|
|
46
|
-
opts.banner =
|
50
|
+
opts.banner = 'Usage: bhook --source /source/path --output /output/path'
|
47
51
|
|
48
|
-
opts.on(
|
49
|
-
String,
|
52
|
+
opts.on('-sSOURCE', '--source=SOURCE',
|
53
|
+
String, 'Path to version controlled directory containing source md files') do |source_path|
|
50
54
|
@args.source = source_path
|
51
55
|
end
|
52
56
|
|
53
|
-
opts.on(
|
54
|
-
String,
|
57
|
+
opts.on('-oOUTPUT', '--output=OUTPUT',
|
58
|
+
String, 'Path to directory where output files are to be generated') do |out_path|
|
55
59
|
@args.output = out_path
|
56
60
|
end
|
57
61
|
|
58
|
-
opts.on(
|
59
|
-
FalseClass,
|
60
|
-
|
62
|
+
opts.on('-w', '--watch',
|
63
|
+
FalseClass,
|
64
|
+
'Continuously watch the source directory for changes and generate output') do
|
61
65
|
@args.watch = true
|
62
66
|
end
|
63
67
|
|
64
|
-
opts.on(
|
65
|
-
FalseClass,
|
66
|
-
|
68
|
+
opts.on('-v', '--verbose',
|
69
|
+
FalseClass,
|
70
|
+
'Print detailed information about files as they are processed') do
|
67
71
|
@args.verbose = true
|
68
72
|
end
|
69
73
|
|
70
|
-
opts.on(
|
71
|
-
String,
|
72
|
-
|
74
|
+
opts.on('-tPATH', '--theme=PATH',
|
75
|
+
String,
|
76
|
+
'Path to directory containing theme files to use when generating html') do |path|
|
73
77
|
@args.theme = path
|
74
78
|
end
|
75
79
|
|
76
|
-
opts.on(
|
77
|
-
String,
|
78
|
-
|
80
|
+
opts.on('--generate-theme=PATH',
|
81
|
+
String,
|
82
|
+
'Generate a baseline theme that you can then modify to your needs') do |path|
|
79
83
|
@args.generate_theme = path
|
80
84
|
end
|
81
85
|
|
82
|
-
opts.on(
|
86
|
+
opts.on('--benchmark',
|
83
87
|
FalseClass,
|
84
|
-
|
88
|
+
'Run a performance benchmark for the specified source') do
|
85
89
|
@args.benchmark = true
|
86
90
|
end
|
87
91
|
|
88
|
-
opts.on(
|
89
|
-
|
90
|
-
exit
|
92
|
+
opts.on('-h', '--help', FalseClass, 'Prints this help') do |_help|
|
93
|
+
@args.help = true
|
91
94
|
end
|
92
|
-
end
|
95
|
+
end
|
93
96
|
end
|
94
97
|
end
|
95
98
|
end
|
data/lib/bhook/config.rb
CHANGED
@@ -2,29 +2,58 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module Bhook
|
5
|
+
#
|
6
|
+
# Valid keys:
|
7
|
+
# - website
|
8
|
+
# - link to place in the footer
|
9
|
+
# - exclude
|
10
|
+
# - list of .md file paths relative to config files
|
5
11
|
class Config
|
6
12
|
extend T::Sig
|
7
|
-
BHOOK_CONFIG_FILE = T.let('.bhook', String)
|
13
|
+
BHOOK_CONFIG_FILE = T.let('.bhook.yml', String)
|
8
14
|
WEBSITE_KEY = T.let('website', String)
|
9
|
-
|
10
|
-
|
11
|
-
|
15
|
+
EXCLUDE_KEY = T.let('exclude', String)
|
16
|
+
|
17
|
+
sig { params(root_dir_path: Pathname, additional_options: T::Hash[String, String]).void }
|
18
|
+
def initialize(root_dir_path, additional_options = {})
|
12
19
|
config_file_path = root_dir_path.join(BHOOK_CONFIG_FILE)
|
13
|
-
config =
|
14
|
-
YAML.load(File.read(config_file_path))
|
15
|
-
else
|
16
|
-
{}
|
17
|
-
end
|
20
|
+
config = load_config(config_file_path).merge(additional_options)
|
18
21
|
@root_dir_path = root_dir_path
|
19
22
|
@website_url = T.let(config[WEBSITE_KEY], T.nilable(String))
|
23
|
+
@excluded_files = T.let(parse_excluded_files(config[EXCLUDE_KEY] || []), T::Array[Pathname])
|
20
24
|
end
|
21
|
-
|
25
|
+
|
22
26
|
sig { params(src_file_path: Pathname, src_file_sha: T.nilable(String)).returns(T.nilable(String)) }
|
23
27
|
def website_url_for(src_file_path, src_file_sha)
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
return unless @website_url && src_file_sha
|
29
|
+
|
30
|
+
relative_file_path = src_file_path.relative_path_from(@root_dir_path)
|
31
|
+
File.join(@website_url, src_file_sha, relative_file_path)
|
32
|
+
end
|
33
|
+
|
34
|
+
sig { params(pathname: Pathname).returns(T::Boolean) }
|
35
|
+
def excluded?(pathname)
|
36
|
+
@excluded_files.include?(pathname)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
sig { params(excluded_files: T::Array[String]).returns(T::Array[Pathname]) }
|
42
|
+
def parse_excluded_files(excluded_files)
|
43
|
+
excluded_files.map { |file_path| @root_dir_path.join(file_path) }
|
44
|
+
end
|
45
|
+
|
46
|
+
sig do
|
47
|
+
params(config_file_path: Pathname).returns(T::Hash[String, T.untyped])
|
48
|
+
end
|
49
|
+
def load_config(config_file_path)
|
50
|
+
if File.exist?(config_file_path)
|
51
|
+
L.debug("Config found: #{config_file_path}")
|
52
|
+
YAML.safe_load(File.read(config_file_path))
|
53
|
+
else
|
54
|
+
L.debug("Config not found: #{config_file_path}")
|
55
|
+
{}
|
27
56
|
end
|
28
57
|
end
|
29
58
|
end
|
30
|
-
end
|
59
|
+
end
|
data/lib/bhook/converter/html.rb
CHANGED
@@ -25,14 +25,12 @@ module Bhook
|
|
25
25
|
sig { params(el: Kramdown::Element, indent: Integer).returns(String) }
|
26
26
|
def convert_header(el, indent)
|
27
27
|
header = super(el, indent)
|
28
|
-
after_h1_strategy = @options[:after_h1_strategy]
|
29
|
-
h1_callback = @options[:h1_callback]
|
30
28
|
src_title = el.options[:raw_text]
|
31
|
-
after_h1_html = after_h1_strategy.call(binding)
|
29
|
+
after_h1_html = @options[:after_h1_strategy].call(binding)
|
32
30
|
|
33
31
|
level = output_header_level(el.options[:level])
|
34
32
|
if level == 1
|
35
|
-
h1_callback.call(src_title)
|
33
|
+
@options[:h1_callback].call(src_title)
|
36
34
|
"#{header}#{' ' * indent}#{after_h1_html}"
|
37
35
|
else
|
38
36
|
header
|
data/lib/bhook/directory.rb
CHANGED
@@ -4,16 +4,15 @@
|
|
4
4
|
module Bhook
|
5
5
|
class Directory
|
6
6
|
extend T::Sig
|
7
|
-
|
7
|
+
|
8
8
|
GIT_DIR = '.git'
|
9
9
|
MD_EXT = '.md'
|
10
|
-
|
10
|
+
|
11
11
|
sig { params(src_path: Pathname, out_path: Pathname).returns(Bhook::Directory) }
|
12
12
|
def self.new_root_directory(src_path, out_path)
|
13
|
-
|
13
|
+
new(src_path, out_path, Git.open(src_path), Bhook::Config.new(src_path))
|
14
14
|
end
|
15
|
-
|
16
|
-
|
15
|
+
|
17
16
|
sig { params(src_path: Pathname, out_path: Pathname, git: Git::Base, config: Bhook::Config).void }
|
18
17
|
def initialize(src_path, out_path, git, config)
|
19
18
|
@src_path = src_path
|
@@ -30,13 +29,11 @@ module Bhook
|
|
30
29
|
FileUtils.mkdir_p(@out_path)
|
31
30
|
L.debug("mkdir: #{@out_path}")
|
32
31
|
@sub_dirs.each { |dir| dir.write!(theme) }
|
33
|
-
@md_files.map do |file|
|
32
|
+
@md_files.map do |file|
|
34
33
|
Thread.new { file.write!(theme) }
|
35
|
-
end.each
|
36
|
-
thread.join
|
37
|
-
end
|
34
|
+
end.each(&:join)
|
38
35
|
end
|
39
|
-
|
36
|
+
|
40
37
|
sig { returns(T::Array[MdFile]) }
|
41
38
|
def all_md_files
|
42
39
|
@md_files + @sub_dirs.map(&:all_md_files).flatten
|
@@ -46,19 +43,23 @@ module Bhook
|
|
46
43
|
def to_s
|
47
44
|
@src_path.to_s
|
48
45
|
end
|
49
|
-
|
46
|
+
|
50
47
|
private
|
51
48
|
|
52
49
|
sig { void }
|
53
50
|
def build_next_level_nodes
|
54
51
|
children = @src_path.children
|
55
52
|
children.delete(@src_path.join(GIT_DIR))
|
56
|
-
|
53
|
+
build_nodes(children)
|
54
|
+
end
|
55
|
+
|
56
|
+
sig { params(children: T::Array[Pathname]).void }
|
57
|
+
def build_nodes(children)
|
57
58
|
file_threads = []
|
58
59
|
children.each do |child_path|
|
59
60
|
if child_path.directory?
|
60
61
|
@sub_dirs << Directory.new(child_path, @out_path, @git, @config)
|
61
|
-
elsif child_path.extname == MD_EXT
|
62
|
+
elsif child_path.extname == MD_EXT && !@config.excluded?(child_path)
|
62
63
|
file_threads << Thread.new { MdFile.new(child_path, @out_path, @git, @config) }
|
63
64
|
end
|
64
65
|
end
|
data/lib/bhook/logger.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: true
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module Bhook
|
5
|
-
|
5
|
+
LOG_FORMATTER = proc { |_severity, _datetime, _progname, msg|
|
6
6
|
"#{Thread.current.object_id} #{msg}\n"
|
7
|
-
}
|
7
|
+
}
|
8
|
+
L = Logger.new($stdout, formatter: LOG_FORMATTER)
|
8
9
|
end
|
data/lib/bhook/md_file.rb
CHANGED
@@ -4,13 +4,19 @@
|
|
4
4
|
module Bhook
|
5
5
|
class MdFile
|
6
6
|
extend T::Sig
|
7
|
-
|
7
|
+
|
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
11
|
sig { returns(Pathname) }
|
12
|
-
attr_reader :src_file_path
|
13
|
-
|
12
|
+
attr_reader :src_file_path, :out_file_path
|
13
|
+
|
14
|
+
sig { returns(T.nilable(String)) }
|
15
|
+
attr_reader :src_file_date, :src_file_sha, :src_file_url
|
16
|
+
|
17
|
+
sig { returns(String) }
|
18
|
+
attr_reader :md
|
19
|
+
|
14
20
|
sig { params(src_file_path: Pathname, out_path: Pathname, git: Git::Base, config: Bhook::Config).void }
|
15
21
|
def initialize(src_file_path, out_path, git, config)
|
16
22
|
L.debug "Reading: #{src_file_path}"
|
@@ -19,31 +25,31 @@ module Bhook
|
|
19
25
|
@out_path = out_path
|
20
26
|
@git = git
|
21
27
|
@config = config
|
22
|
-
|
23
|
-
|
24
|
-
@src_file_sha = T.let(src_file_sha, T.nilable(String))
|
28
|
+
@out_file_path = T.let(@out_path.join(out_file_name), Pathname)
|
29
|
+
initialize_file_details
|
25
30
|
end
|
26
31
|
|
27
32
|
sig { params(theme: Bhook::Theme).void }
|
28
33
|
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)
|
32
|
-
|
33
34
|
L.debug "Processing: #{@src_file_sha || 'unversioned'} #{@src_file_path}"
|
34
|
-
rendered_page = theme.render_page(@md, @src_file_sha, @src_file_date,
|
35
|
+
rendered_page = theme.render_page(@md, @src_file_sha, @src_file_date, @src_file_url)
|
35
36
|
|
36
37
|
L.debug "Writing: #{@src_file_sha} #{out_file_path}"
|
37
|
-
File.write(out_file_path, rendered_page)
|
38
|
+
File.write(@out_file_path, rendered_page)
|
38
39
|
end
|
39
40
|
|
40
|
-
sig { returns(String) }
|
41
|
-
def to_s
|
42
|
-
@src_file_path.to_s
|
43
|
-
end
|
44
|
-
|
45
41
|
private
|
46
|
-
|
42
|
+
|
43
|
+
sig { returns(Pathname) }
|
44
|
+
def out_file_name
|
45
|
+
@src_file_path.basename.sub(/\.md$/, '.html')
|
46
|
+
end
|
47
|
+
|
48
|
+
sig { returns(T.nilable(String)) }
|
49
|
+
def file_url
|
50
|
+
@config.website_url_for(@src_file_path, @src_file_sha)
|
51
|
+
end
|
52
|
+
|
47
53
|
sig { returns(T::Array[String]) }
|
48
54
|
def load_git_file_metadata
|
49
55
|
@git.lib.send(:command, 'log',
|
@@ -53,5 +59,13 @@ module Bhook
|
|
53
59
|
'--',
|
54
60
|
@src_file_path).split('|')
|
55
61
|
end
|
62
|
+
|
63
|
+
sig { void }
|
64
|
+
def initialize_file_details
|
65
|
+
file_date, file_sha = load_git_file_metadata
|
66
|
+
@src_file_date = T.let(file_date, T.nilable(String))
|
67
|
+
@src_file_sha = T.let(file_sha, T.nilable(String))
|
68
|
+
@src_file_url = T.let(file_url, T.nilable(String))
|
69
|
+
end
|
56
70
|
end
|
57
71
|
end
|
data/lib/bhook/theme/page.erb
CHANGED
@@ -48,7 +48,16 @@
|
|
48
48
|
padding: 1em;
|
49
49
|
}
|
50
50
|
</style>
|
51
|
-
|
51
|
+
<!-- Global site tag (gtag.js) - Google Analytics -->
|
52
|
+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-CT9TWBW0WR"></script>
|
53
|
+
<script>
|
54
|
+
window.dataLayer = window.dataLayer || [];
|
55
|
+
function gtag(){dataLayer.push(arguments);}
|
56
|
+
gtag('js', new Date());
|
57
|
+
|
58
|
+
gtag('config', 'G-CT9TWBW0WR');
|
59
|
+
</script>
|
60
|
+
<title><%= src_title -%></title>
|
52
61
|
</head>
|
53
62
|
<body>
|
54
63
|
<div class="body container">
|
@@ -69,16 +78,5 @@
|
|
69
78
|
</div>
|
70
79
|
</div>
|
71
80
|
</div>
|
72
|
-
<script type='text/javascript'>
|
73
|
-
var _gaq = _gaq || [];
|
74
|
-
_gaq.push(['_setAccount', 'UA-24685691-1']);
|
75
|
-
_gaq.push(['_trackPageview']);
|
76
|
-
|
77
|
-
(function() {
|
78
|
-
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
79
|
-
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
80
|
-
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
81
|
-
})();
|
82
|
-
</script>
|
83
81
|
</body>
|
84
82
|
</html>
|