jekyll-last-commit 0.0.2 → 0.0.3

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: 545441f5818c9b03538f579d7635922c4d5d7b8e589f8260be880d2edc06173f
4
+ data.tar.gz: a8ef1cec4beedd36ce060af9844e93be188e17f9cd40c3b3f20c1a0b2c08aada
5
5
  SHA512:
6
- metadata.gz: ffc9f7cb61b802b5b57807c0cf7e3aac824bb7300c1b4265b0afc5d235cca4fd579ad8db5e96a6e909fcb736a1a44bd0541968885f536b10a290e84f905e75be
7
- data.tar.gz: d77971574e7154b23109361195b2eae6465bd88dabbd647cab03a017d25d34a95318d5004571e6b02d1da864c97cd3ffe04a5f149cfdd413e45daef0908520ec
6
+ metadata.gz: 43926e5afb45d6af9d59d4b775d18bc35dd4df9c75b2a70ea5f40b839b0bf96405088767d5e6e61e90a91e8c5f41d5c7ef6be7865cfcedbdaf4153433f77c067
7
+ data.tar.gz: fa3dedb65542e16d3c02b9ce1fa50ed0082fe029e89c5a649b074859f4b0f6ff42969dec6c8f218d495035acb90219405c629bea8f42ae7837c69ccdd4dd86b4
@@ -0,0 +1,67 @@
1
+ require 'jekyll'
2
+
3
+ module JekyllLastCommit
4
+ class Generator < Jekyll::Generator
5
+
6
+ def generate(site)
7
+ repo_man = JekyllLastCommit::RepoMan.new(site.source)
8
+ repo_man.discover_repo()
9
+ repo_man.discover_commits(site.documents.map {|d| d.relative_path })
10
+ repo_man.discover_commits(site.pages.map {|p| p.relative_path })
11
+
12
+ date_format = site.config.dig('jekyll-last-commit', 'date_format')
13
+ date_format ||= '%B %d, %Y'
14
+
15
+ should_fall_back_to_mtime = site.config.dig('jekyll-last-commit', 'should_fall_back_to_mtime')
16
+ should_fall_back_to_mtime = should_fall_back_to_mtime.nil? ? true : should_fall_back_to_mtime
17
+
18
+ site.documents.each do |document|
19
+ commit = repo_man.find_commit(document.relative_path)
20
+
21
+ if commit.nil?
22
+ if should_fall_back_to_mtime
23
+ path_document = Jekyll.sanitized_path(site.source, document.relative_path)
24
+
25
+ if File.file?(path_document)
26
+ raw_time = Time.at(File.mtime(path_document).to_i)
27
+
28
+ Jekyll.logger.warn "JekyllLastCommit: unable to find commit information for #{document.relative_path}. falling back to `mtime` for last_modified_at"
29
+ document.data['last_modified_at'] = raw_time
30
+ document.data['last_modified_at_formatted'] = raw_time.strftime(date_format)
31
+ end
32
+ end
33
+ else
34
+ raw_time = Time.at(commit["time"].to_i)
35
+
36
+ document.data['last_commit'] = commit
37
+ document.data['last_modified_at'] = raw_time
38
+ document.data['last_modified_at_formatted'] = raw_time.strftime(date_format)
39
+ end
40
+ end
41
+
42
+ site.pages.each do |page|
43
+ commit = repo_man.find_commit(page.relative_path)
44
+
45
+ if commit.nil?
46
+ if should_fall_back_to_mtime
47
+ path_page = Jekyll.sanitized_path(site.source, page.relative_path)
48
+
49
+ if File.file?(path_page)
50
+ raw_time = Time.at(File.mtime(path_page).to_i)
51
+ page.data['last_modified_at'] = raw_time
52
+ page.data['last_modified_at_formatted'] = raw_time.strftime(date_format)
53
+ end
54
+ end
55
+
56
+ else
57
+ raw_time = Time.at(commit["time"].to_i)
58
+
59
+ page.data['last_commit'] = commit
60
+ page.data['last_modified_at'] = raw_time
61
+ page.data['last_modified_at_formatted'] = raw_time.strftime(date_format)
62
+ end
63
+ end
64
+ end
65
+
66
+ end
67
+ 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.3
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: 2022-12-18 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