jekyll-last-commit 0.0.2 → 0.0.3

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