jekyll-last-commit 0.0.2 → 0.0.4

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