jekyll-last-commit 0.0.2 → 0.0.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: 4b37651ca4010358f65dc170a7a30a6e59eadc345c0f63c785a8a591f38fb6c0
4
- data.tar.gz: 70248fe1802e7901b23a7fccc39e090ac7c3a4119b2ba05829ce082fd29cf83c
3
+ metadata.gz: b5e8ca51ac4e8b52849fcfcfec308024e65fcfb88535c4d95a2543aa098326c4
4
+ data.tar.gz: 64dfaa2a3f92cbcc7b183492143406619b0d3384124c83269be5b2eaa5d185d9
5
5
  SHA512:
6
- metadata.gz: ffc9f7cb61b802b5b57807c0cf7e3aac824bb7300c1b4265b0afc5d235cca4fd579ad8db5e96a6e909fcb736a1a44bd0541968885f536b10a290e84f905e75be
7
- data.tar.gz: d77971574e7154b23109361195b2eae6465bd88dabbd647cab03a017d25d34a95318d5004571e6b02d1da864c97cd3ffe04a5f149cfdd413e45daef0908520ec
6
+ metadata.gz: b21f0e0acb5a08c19fce6f53b8ab3fd4112839cea6edf668409f92cba53d267cf07137ae39c5e87bd5adfe1178e52eed59312596f0ef480d14a657da9f5a0760
7
+ data.tar.gz: 1c5a7f7d3195e2bd98cb55874a7279a02d78e0adfb8a8985d09ee7a1b3b34e749294098d6635a088100f1db8d62c967323bba2cc7cedab36e42034664929e06d
@@ -0,0 +1,108 @@
1
+ require 'jekyll'
2
+
3
+ module JekyllLastCommit
4
+ class Generator < Jekyll::Generator
5
+ priority :highest
6
+
7
+ def generate(site)
8
+ @site = site
9
+
10
+ @repo_man = JekyllLastCommit::RepoMan.new(site.source)
11
+ @repo_man.discover_repo()
12
+
13
+ @date_format = site.config.dig('jekyll-last-commit', 'date_format')
14
+ @date_format ||= '%B %d, %Y'
15
+
16
+ @should_fall_back_to_mtime = site.config.dig('jekyll-last-commit', 'should_fall_back_to_mtime')
17
+ @should_fall_back_to_mtime ||= true
18
+
19
+ @repo_man.discover_commits(site.documents.map {|d| d.relative_path })
20
+ populate_jekyll(site.documents)
21
+
22
+ @repo_man.discover_commits(site.pages.map {|p| p.relative_path })
23
+ populate_jekyll(site.pages)
24
+
25
+ index_static_files = site.config.dig('jekyll-last-commit', 'index_static_files')
26
+ index_static_files ||= false
27
+ if index_static_files
28
+ @repo_man.discover_commits(site.static_files.map {|sf| '.' + sf.relative_path })
29
+ populate_jekyll(site.static_files, '.')
30
+ end
31
+
32
+ index_data_files = site.config.dig('jekyll-last-commit', 'index_data_files')
33
+ index_data_files ||= false
34
+ if index_data_files
35
+ data_file_extensions = ['.yml', '.yaml', '.json', '.tsv', '.csv']
36
+ data_files = []
37
+ site.data.keys.each do |data_file|
38
+ data_file_extensions.each do |data_file_extension|
39
+ data_file_name = data_file + data_file_extension
40
+ if File.file?('./_data/' + data_file_name)
41
+ data_files.append(data_file_name)
42
+ break
43
+ end
44
+ end
45
+ end
46
+
47
+ data_files_key = site.config.dig('jekyll-last-commit', 'data_files_key')
48
+ data_files_key ||= 'meta'
49
+
50
+ @repo_man.discover_commits(data_files.map {|df| './_data/' + df })
51
+
52
+ site.data[data_files_key] = {}
53
+ populate_data(data_files, site.data[data_files_key], './_data/')
54
+ end
55
+ end
56
+
57
+ def populate_jekyll(files, prepend_path = '')
58
+ files.each do |file|
59
+ commit = @repo_man.find_commit(prepend_path + file.relative_path)
60
+
61
+ if commit.nil?
62
+ if @should_fall_back_to_mtime
63
+ path_file = Jekyll.sanitized_path(@site.source, prepend_path + file.relative_path)
64
+
65
+ if File.file?(path_file)
66
+ raw_time = Time.at(File.mtime(path_file).to_i)
67
+ file.data['commit'] = prepend_path + file.relative_path
68
+ file.data['last_modified_at'] = raw_time
69
+ file.data['last_modified_at_formatted'] = raw_time.strftime(@date_format)
70
+ end
71
+ end
72
+
73
+ else
74
+ raw_time = Time.at(commit["time"].to_i)
75
+ file.data['last_commit'] = commit
76
+ file.data['last_modified_at'] = raw_time
77
+ file.data['last_modified_at_formatted'] = raw_time.strftime(@date_format)
78
+ end
79
+ end
80
+ end
81
+
82
+ def populate_data(source, output = {}, prepend_path = '')
83
+ source.each do |file|
84
+ output[file] ||= {}
85
+
86
+ relative_path = prepend_path + file
87
+ commit = @repo_man.find_commit(relative_path)
88
+
89
+ if commit.nil?
90
+ if @should_fall_back_to_mtime
91
+ path_file = Jekyll.sanitized_path(@site.source, relative_path)
92
+
93
+ if File.file?(file)
94
+ raw_time = Time.at(File.mtime(path_file).to_i)
95
+ output[file]['last_modified_at'] = raw_time
96
+ output[file]['last_modified_at_formatted'] = raw_time.strftime(@date_format)
97
+ end
98
+ end
99
+ else
100
+ raw_time = Time.at(commit['time'].to_i)
101
+ output[file]['last_commit'] = commit
102
+ output[file]['last_modified_at'] = raw_time
103
+ output[file]['last_modified_at_formatted'] = raw_time.strftime(@date_format)
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,104 @@
1
+ require 'pathname'
2
+ require 'rugged'
3
+ require 'set'
4
+
5
+ module JekyllLastCommit
6
+ class RepoMan
7
+
8
+ def initialize(path_site)
9
+ @path_site = Pathname.new(path_site)
10
+ end
11
+
12
+ def discover_repo
13
+ begin
14
+ @repo = Rugged::Repository.discover(@path_site)
15
+
16
+ path_dot_git = Pathname.new(@repo.path)
17
+ path_repo = path_dot_git.parent
18
+
19
+ # necessary to handle situations where site is not top level in repo
20
+ @path_relative = @path_site.relative_path_from(path_repo)
21
+
22
+ rescue
23
+ Jekyll.logger.warn "JekyllLastCommit: unable to find git repository at #{@path_site}"
24
+ end
25
+ end
26
+
27
+ def discover_commits(relative_file_paths)
28
+ return if @repo.nil?
29
+
30
+ document_paths = relative_file_paths.map {|rfp| generate_relative_path(rfp) }.to_set
31
+
32
+ # gets updated with renames pointing to original path
33
+ paths_lookup = document_paths.reduce({}) do |memo, original_path|
34
+ memo[original_path] = original_path
35
+ memo
36
+ end
37
+
38
+ # starting with the most recent commit, look for data on paths_undetermined
39
+ walker = Rugged::Walker.new(@repo)
40
+ walker.push(@repo.head.target.oid) # start with most recent commit
41
+
42
+ find_similar_opts = {rename_limit: 1000}
43
+
44
+ @paths_determined ||= {}
45
+
46
+ walker.each_with_index do |commit, i|
47
+ diff = commit.diff
48
+
49
+ # ignore renames
50
+ diff.find_similar!(**find_similar_opts)
51
+
52
+ diff.deltas.each do |delta|
53
+ new_file_path = delta.new_file[:path]
54
+
55
+ original_path = paths_lookup[new_file_path]
56
+
57
+ if document_paths.include?(new_file_path)
58
+ if delta.status == :renamed
59
+ # special case
60
+ old_file_path = delta.old_file[:path]
61
+
62
+ paths_lookup[old_file_path] = original_path
63
+
64
+ # no longer looking for the new file, looking for the old file
65
+ document_paths.delete(new_file_path)
66
+ document_paths.add(old_file_path)
67
+ else
68
+ @paths_determined[original_path] = commit
69
+ document_paths.delete(new_file_path)
70
+ end
71
+ end
72
+ end
73
+
74
+ break if document_paths.empty?
75
+ end
76
+ end
77
+
78
+ def find_commit(relative_path)
79
+ return nil if @repo.nil?
80
+
81
+ commit = @paths_determined[generate_relative_path(relative_path)]
82
+
83
+ return nil if commit.nil?
84
+
85
+ commit_hash = commit.to_hash
86
+ .tap {|h| h.delete(:tree) } # just reduce noise; can always add back later
87
+ .tap {|h| h.delete(:parents) }
88
+ .transform_keys(&:to_s) # transform symbols to keys so liquid will render
89
+ .transform_values {|v| v.is_a?(Hash) ? v.transform_keys(&:to_s) : v.strip! }
90
+ commit_hash['sha'] = commit.oid
91
+ commit_hash['time'] = commit.time
92
+ commit_hash['time_epoch'] = commit.time.to_i
93
+
94
+ commit_hash
95
+ end
96
+
97
+ private
98
+
99
+ def generate_relative_path(relative_path)
100
+ (@path_relative + Pathname.new(relative_path)).to_s
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,31 @@
1
+ module JekyllLastCommit
2
+ class Tag < Liquid::Tag
3
+ def initialize(tag_name, date_format, tokens)
4
+ super
5
+ @date_format = date_format.empty? ? nil : date_format.strip
6
+ end
7
+
8
+ def render(context)
9
+ @date_format ||= default_date_format(context)
10
+
11
+ page = context.registers[:page]
12
+
13
+ time = page['last_modified_at']
14
+
15
+ time.nil? ? "" : Time.at(time.to_i).strftime(@date_format)
16
+ end
17
+
18
+ def default_date_format(context)
19
+ site = context.registers[:site]
20
+
21
+ date_format = site.config.dig('jekyll-last-commit', 'date_format')
22
+ date_format ||= '%B %d, %Y'
23
+
24
+ date_format
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ Liquid::Template.register_tag('last_modified_at', JekyllLastCommit::Tag)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-last-commit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kip Landergren
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-17 00:00:00.000000000 Z
11
+ date: 2024-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jekyll
@@ -52,6 +52,9 @@ extensions: []
52
52
  extra_rdoc_files: []
53
53
  files:
54
54
  - lib/jekyll-last-commit.rb
55
+ - lib/jekyll-last-commit/generator.rb
56
+ - lib/jekyll-last-commit/repo_man.rb
57
+ - lib/jekyll-last-commit/tag.rb
55
58
  homepage: https://github.com/klandergren/jekyll-last-commit
56
59
  licenses:
57
60
  - MIT