From 555e71b7902c32d83c34a3fb2f658728c5d62463 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 15 Jul 2024 13:03:00 +0700 Subject: [PATCH 1/4] add CacheBustFilters --- docs/Gemfile | 3 +- docs/Gemfile.lock | 195 +---------------------------- docs/_layouts/default.html | 10 +- docs/_plugins/cache_bust_filter.rb | 87 +++++++++++++ 4 files changed, 96 insertions(+), 199 deletions(-) create mode 100644 docs/_plugins/cache_bust_filter.rb diff --git a/docs/Gemfile b/docs/Gemfile index 91971b594b4f..73ced17fea02 100644 --- a/docs/Gemfile +++ b/docs/Gemfile @@ -8,7 +8,8 @@ source "https://rubygems.org" # This will help ensure the proper Jekyll version is running. # Happy Jekylling! -gem "github-pages", group: :jekyll_plugins +gem 'jekyll', group: :jekyll_plugins +gem 'kramdown-parser-gfm' # If you have any plugins, put them here! group :jekyll_plugins do diff --git a/docs/Gemfile.lock b/docs/Gemfile.lock index de99bbcb48ef..4c492ae1e251 100644 --- a/docs/Gemfile.lock +++ b/docs/Gemfile.lock @@ -1,91 +1,16 @@ GEM remote: https://rubygems.org/ specs: - activesupport (6.0.5) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2, >= 2.2.2) addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.11.1) colorator (1.1.0) - commonmarker (0.23.10) concurrent-ruby (1.1.10) - dnsruby (1.61.9) - simpleidn (~> 0.1) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) - ethon (0.15.0) - ffi (>= 1.15.0) eventmachine (1.2.7) - execjs (2.8.1) - faraday (2.3.0) - faraday-net_http (~> 2.0) - ruby2_keywords (>= 0.0.4) - faraday-net_http (2.0.3) ffi (1.15.5) forwardable-extended (2.6.0) - gemoji (3.0.1) - github-pages (228) - github-pages-health-check (= 1.17.9) - jekyll (= 3.9.3) - jekyll-avatar (= 0.7.0) - jekyll-coffeescript (= 1.1.1) - jekyll-commonmark-ghpages (= 0.4.0) - jekyll-default-layout (= 0.1.4) - jekyll-feed (= 0.15.1) - jekyll-gist (= 1.5.0) - jekyll-github-metadata (= 2.13.0) - jekyll-include-cache (= 0.2.1) - jekyll-mentions (= 1.6.0) - jekyll-optional-front-matter (= 0.3.2) - jekyll-paginate (= 1.1.0) - jekyll-readme-index (= 0.3.0) - jekyll-redirect-from (= 0.16.0) - jekyll-relative-links (= 0.6.1) - jekyll-remote-theme (= 0.4.3) - jekyll-sass-converter (= 1.5.2) - jekyll-seo-tag (= 2.8.0) - jekyll-sitemap (= 1.4.0) - jekyll-swiss (= 1.0.0) - jekyll-theme-architect (= 0.2.0) - jekyll-theme-cayman (= 0.2.0) - jekyll-theme-dinky (= 0.2.0) - jekyll-theme-hacker (= 0.2.0) - jekyll-theme-leap-day (= 0.2.0) - jekyll-theme-merlot (= 0.2.0) - jekyll-theme-midnight (= 0.2.0) - jekyll-theme-minimal (= 0.2.0) - jekyll-theme-modernist (= 0.2.0) - jekyll-theme-primer (= 0.6.0) - jekyll-theme-slate (= 0.2.0) - jekyll-theme-tactile (= 0.2.0) - jekyll-theme-time-machine (= 0.2.0) - jekyll-titles-from-headings (= 0.5.3) - jemoji (= 0.12.0) - kramdown (= 2.3.2) - kramdown-parser-gfm (= 1.1.0) - liquid (= 4.0.4) - mercenary (~> 0.3) - minima (= 2.5.1) - nokogiri (>= 1.13.6, < 2.0) - rouge (= 3.26.0) - terminal-table (~> 1.4) - github-pages-health-check (1.17.9) - addressable (~> 2.3) - dnsruby (~> 1.60) - octokit (~> 4.0) - public_suffix (>= 3.0, < 5.0) - typhoeus (~> 1.3) - html-pipeline (2.14.2) - activesupport (>= 2) - nokogiri (>= 1.4) http_parser.rb (0.8.0) i18n (0.9.5) concurrent-ruby (~> 1.0) @@ -102,101 +27,16 @@ GEM pathutil (~> 0.9) rouge (>= 1.7, < 4) safe_yaml (~> 1.0) - jekyll-avatar (0.7.0) - jekyll (>= 3.0, < 5.0) - jekyll-coffeescript (1.1.1) - coffee-script (~> 2.2) - coffee-script-source (~> 1.11.1) - jekyll-commonmark (1.4.0) - commonmarker (~> 0.22) - jekyll-commonmark-ghpages (0.4.0) - commonmarker (~> 0.23.7) - jekyll (~> 3.9.0) - jekyll-commonmark (~> 1.4.0) - rouge (>= 2.0, < 5.0) - jekyll-default-layout (0.1.4) - jekyll (~> 3.0) jekyll-feed (0.15.1) jekyll (>= 3.7, < 5.0) - jekyll-gist (1.5.0) - octokit (~> 4.2) - jekyll-github-metadata (2.13.0) - jekyll (>= 3.4, < 5.0) - octokit (~> 4.0, != 4.4.0) - jekyll-include-cache (0.2.1) - jekyll (>= 3.7, < 5.0) - jekyll-mentions (1.6.0) - html-pipeline (~> 2.3) - jekyll (>= 3.7, < 5.0) - jekyll-optional-front-matter (0.3.2) - jekyll (>= 3.0, < 5.0) - jekyll-paginate (1.1.0) - jekyll-readme-index (0.3.0) - jekyll (>= 3.0, < 5.0) jekyll-redirect-from (0.16.0) jekyll (>= 3.3, < 5.0) - jekyll-relative-links (0.6.1) - jekyll (>= 3.3, < 5.0) - jekyll-remote-theme (0.4.3) - addressable (~> 2.0) - jekyll (>= 3.5, < 5.0) - jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) - rubyzip (>= 1.3.0, < 3.0) jekyll-sass-converter (1.5.2) sass (~> 3.4) jekyll-seo-tag (2.8.0) jekyll (>= 3.8, < 5.0) - jekyll-sitemap (1.4.0) - jekyll (>= 3.7, < 5.0) - jekyll-swiss (1.0.0) - jekyll-theme-architect (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-cayman (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-dinky (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-hacker (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-leap-day (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-merlot (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-midnight (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-minimal (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-modernist (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-primer (0.6.0) - jekyll (> 3.5, < 5.0) - jekyll-github-metadata (~> 2.9) - jekyll-seo-tag (~> 2.0) - jekyll-theme-slate (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-tactile (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-theme-time-machine (0.2.0) - jekyll (> 3.5, < 5.0) - jekyll-seo-tag (~> 2.0) - jekyll-titles-from-headings (0.5.3) - jekyll (>= 3.3, < 5.0) jekyll-watch (2.2.1) listen (~> 3.0) - jemoji (0.12.0) - gemoji (~> 3.0) - html-pipeline (~> 2.2) - jekyll (>= 3.0, < 5.0) kramdown (2.3.2) rexml kramdown-parser-gfm (1.1.0) @@ -206,53 +46,21 @@ GEM rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.3.6) - minima (2.5.1) - jekyll (>= 3.5, < 5.0) - jekyll-feed (~> 0.9) - jekyll-seo-tag (~> 2.1) - minitest (5.16.2) - nokogiri (1.15.4-arm64-darwin) - racc (~> 1.4) - nokogiri (1.15.4-x86_64-darwin) - racc (~> 1.4) - octokit (4.25.1) - faraday (>= 1, < 3) - sawyer (~> 0.9) pathutil (0.16.2) forwardable-extended (~> 2.6) public_suffix (4.0.7) - racc (1.6.0) rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) rexml (3.2.5) rouge (3.26.0) - ruby2_keywords (0.0.5) - rubyzip (2.3.2) safe_yaml (1.0.5) sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - sawyer (0.9.2) - addressable (>= 2.3.5) - faraday (>= 0.17.3, < 3) - simpleidn (0.2.1) - unf (~> 0.1.4) - terminal-table (1.8.0) - unicode-display_width (~> 1.1, >= 1.1.1) - thread_safe (0.3.6) - typhoeus (1.4.0) - ethon (>= 0.9.0) - tzinfo (1.2.9) - thread_safe (~> 0.1) - unf (0.1.4) - unf_ext - unf_ext (0.0.8.2) - unicode-display_width (1.8.0) webrick (1.7.0) - zeitwerk (2.6.0) PLATFORMS arm64-darwin-22 @@ -261,11 +69,12 @@ PLATFORMS x86_64-darwin-21 DEPENDENCIES - github-pages http_parser.rb (~> 0.6.0) + jekyll jekyll-feed (~> 0.12) jekyll-redirect-from jekyll-seo-tag + kramdown-parser-gfm liquid (~> 4.0.4) tzinfo (~> 1.2) tzinfo-data diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index cc45e83efa59..f83af009c1ea 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -5,15 +5,15 @@ Expensify Help - - + + - - - + + + diff --git a/docs/_plugins/cache_bust_filter.rb b/docs/_plugins/cache_bust_filter.rb new file mode 100644 index 000000000000..0c6f7cfaeb2e --- /dev/null +++ b/docs/_plugins/cache_bust_filter.rb @@ -0,0 +1,87 @@ +# Note: Github doesn't allow plugins to execute (safemode). These filters won't work on github pages. +module Jekyll + module CacheBustFilters + # A simple class to handle md5 hexdigesting + # Initalizing params: + # * file_name - String - required - this is both filename to which the md5 + # hash will be appended to, and will be read for hexdigest in the absense + # of a passed in directory. + # * directory - String - optional - path of directory files that will be + # recursively read and passed into hexdigest + class CacheDigester + require 'digest/md5' + + attr_accessor :file_name, :directory + + def initialize(file_name:, directory: nil) + self.file_name = file_name + self.directory = directory + puts "Initialized CacheDigester with file_name: #{file_name}, directory: #{directory}" + end + + def digest! + puts "Generating digest for file: #{file_name}" + digest = [file_name, '?v=', Digest::MD5.hexdigest(file_contents)].join + digest + end + + private + + def directory_files_content + target_path = File.join(directory, '**', '*') + puts "Reading files from directory: #{target_path}" + content = Dir[target_path].map { |f| File.read(f) unless File.directory?(f) }.join + content + end + + def file_content + puts "Reading content from file: #{file_name}" + content = File.read(file_name) + content + end + + def file_contents + if is_directory? + puts "Reading content from file (not a directory)" + file_content + else + puts "Reading content from directory" + directory_files_content + end + end + + def is_directory? + directory.nil? + end + end + + # Gets Md5 contents of target file (assumed to be using the full path) + # and appends a hash end of to asset file reference. Ensures deployed + # asset files are "cachebust-ed" every time the file changes + def md5_cache_bust(file_name) + puts "md5_cache_bust called with file_name: #{file_name}" + CacheDigester.new(file_name: file_name).digest! + end + + # Gets Md5 contents of all sass assets (assumed to be in /_sass/ ) + # and appends a hash end of the target asset file. Ensures deployed + # sass bassed CSS files are "cachebust-ed" every time the files change + def sass_cache_bust(file_name) + puts "sass_cache_bust called with file_name: #{file_name}" + CacheDigester.new(file_name: file_name, directory: '_sass').digest! + end + + # Gets Md5 contents of all js assets in _assets/javascripts/ + # and appends a hash end of the target asset file. Ensures deployed + # files are "cachebust-ed" every time the files change. Using + # jekyll-assests requires first capturing the asset_path string, and + # passing the path to this filter in a subsequent liquid call + def js_cache_bust(file_name) + puts "js_cache_bust called with file_name: #{file_name}" + file_name.gsub!('.js', '.min.js') if ENV['JEKYLL_ENV'] == 'production' + CacheDigester.new(file_name: file_name, directory: '_assets/javascripts').digest! + end + end +end + +Liquid::Template.register_filter(Jekyll::CacheBustFilters) \ No newline at end of file From 81e91307f6051a10176bb10918d419b330870f11 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Mon, 15 Jul 2024 13:57:59 +0700 Subject: [PATCH 2/4] make cache_bust filter generic for supported assets --- docs/_layouts/default.html | 10 +-- docs/_plugins/cache_bust_filter.rb | 129 ++++++++++------------------- 2 files changed, 51 insertions(+), 88 deletions(-) diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index f83af009c1ea..59fd49af7710 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -5,15 +5,15 @@ Expensify Help - - + + - - - + + + diff --git a/docs/_plugins/cache_bust_filter.rb b/docs/_plugins/cache_bust_filter.rb index 0c6f7cfaeb2e..7bda68eb1a6a 100644 --- a/docs/_plugins/cache_bust_filter.rb +++ b/docs/_plugins/cache_bust_filter.rb @@ -1,87 +1,50 @@ -# Note: Github doesn't allow plugins to execute (safemode). These filters won't work on github pages. -module Jekyll - module CacheBustFilters - # A simple class to handle md5 hexdigesting - # Initalizing params: - # * file_name - String - required - this is both filename to which the md5 - # hash will be appended to, and will be read for hexdigest in the absense - # of a passed in directory. - # * directory - String - optional - path of directory files that will be - # recursively read and passed into hexdigest - class CacheDigester - require 'digest/md5' - - attr_accessor :file_name, :directory - - def initialize(file_name:, directory: nil) - self.file_name = file_name - self.directory = directory - puts "Initialized CacheDigester with file_name: #{file_name}, directory: #{directory}" - end - - def digest! - puts "Generating digest for file: #{file_name}" - digest = [file_name, '?v=', Digest::MD5.hexdigest(file_contents)].join - digest - end - - private - - def directory_files_content - target_path = File.join(directory, '**', '*') - puts "Reading files from directory: #{target_path}" - content = Dir[target_path].map { |f| File.read(f) unless File.directory?(f) }.join - content - end - - def file_content - puts "Reading content from file: #{file_name}" - content = File.read(file_name) - content - end +require 'digest' - def file_contents - if is_directory? - puts "Reading content from file (not a directory)" - file_content - else - puts "Reading content from directory" - directory_files_content - end - end - - def is_directory? - directory.nil? - end - end - - # Gets Md5 contents of target file (assumed to be using the full path) - # and appends a hash end of to asset file reference. Ensures deployed - # asset files are "cachebust-ed" every time the file changes - def md5_cache_bust(file_name) - puts "md5_cache_bust called with file_name: #{file_name}" - CacheDigester.new(file_name: file_name).digest! - end - - # Gets Md5 contents of all sass assets (assumed to be in /_sass/ ) - # and appends a hash end of the target asset file. Ensures deployed - # sass bassed CSS files are "cachebust-ed" every time the files change - def sass_cache_bust(file_name) - puts "sass_cache_bust called with file_name: #{file_name}" - CacheDigester.new(file_name: file_name, directory: '_sass').digest! - end - - # Gets Md5 contents of all js assets in _assets/javascripts/ - # and appends a hash end of the target asset file. Ensures deployed - # files are "cachebust-ed" every time the files change. Using - # jekyll-assests requires first capturing the asset_path string, and - # passing the path to this filter in a subsequent liquid call - def js_cache_bust(file_name) - puts "js_cache_bust called with file_name: #{file_name}" - file_name.gsub!('.js', '.min.js') if ENV['JEKYLL_ENV'] == 'production' - CacheDigester.new(file_name: file_name, directory: '_assets/javascripts').digest! - end +module Jekyll + module CacheBustFilter + def cache_bust(input) + puts "Processing asset: #{input}" + + # Get the file extension + ext = File.extname(input) + puts "File extension: #{ext}" + + # Define a list of supported asset types + supported_assets = %w[.css .js .png .jpg .jpeg .gif .svg .woff .woff2 .ttf .eot] + + # Check if the asset type is supported + if supported_assets.include?(ext) + puts "Asset type supported: #{ext}" + + # Compute the file hash + site_dest = @context.registers[:site].dest + puts "Site destination directory: #{site_dest}" + + file_path = File.join(site_dest, input) + puts "Constructed file path: #{file_path}" + + if File.exist?(file_path) + puts "File exists: #{file_path}" + + file_content = File.read(file_path) + file_hash = Digest::MD5.hexdigest(file_content) + puts "File hash: #{file_hash}" + + "#{input}?v=#{file_hash}" + else + puts "File does not exist: #{file_path}" + # Return the input unchanged if the file does not exist + input + end + else + puts "Asset type not supported: #{ext}" + # Return the input unchanged if the asset type is not supported + input + end + end end end -Liquid::Template.register_filter(Jekyll::CacheBustFilters) \ No newline at end of file +Liquid::Template.register_filter(Jekyll::CacheBustFilter) + + From 8b27f1902e413405b4fee11039646b4592c79cac Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Thu, 18 Jul 2024 08:00:32 +0700 Subject: [PATCH 3/4] Change site_dest to site_source, move main asset string to _config.yml, add specific case for main css --- docs/_config.yml | 1 + docs/_layouts/default.html | 2 +- docs/_plugins/cache_bust_filter.rb | 100 ++++++++++++++++------------- 3 files changed, 59 insertions(+), 44 deletions(-) diff --git a/docs/_config.yml b/docs/_config.yml index 888f0b24a91e..7fe5222d1314 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -6,6 +6,7 @@ author: Expensify logo: /assets/images/expensify-help.svg repository: Expensify/App open_url: true +main_style: /assets/css/styles.css defaults: - scope: diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index 59fd49af7710..472887177e74 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -6,7 +6,7 @@ Expensify Help - + diff --git a/docs/_plugins/cache_bust_filter.rb b/docs/_plugins/cache_bust_filter.rb index 7bda68eb1a6a..abb1545fdd28 100644 --- a/docs/_plugins/cache_bust_filter.rb +++ b/docs/_plugins/cache_bust_filter.rb @@ -2,49 +2,63 @@ module Jekyll module CacheBustFilter - def cache_bust(input) - puts "Processing asset: #{input}" - - # Get the file extension - ext = File.extname(input) - puts "File extension: #{ext}" - - # Define a list of supported asset types - supported_assets = %w[.css .js .png .jpg .jpeg .gif .svg .woff .woff2 .ttf .eot] - - # Check if the asset type is supported - if supported_assets.include?(ext) - puts "Asset type supported: #{ext}" - - # Compute the file hash - site_dest = @context.registers[:site].dest - puts "Site destination directory: #{site_dest}" - - file_path = File.join(site_dest, input) - puts "Constructed file path: #{file_path}" - - if File.exist?(file_path) - puts "File exists: #{file_path}" - - file_content = File.read(file_path) - file_hash = Digest::MD5.hexdigest(file_content) - puts "File hash: #{file_hash}" - - "#{input}?v=#{file_hash}" - else - puts "File does not exist: #{file_path}" - # Return the input unchanged if the file does not exist - input - end - else - puts "Asset type not supported: #{ext}" - # Return the input unchanged if the asset type is not supported - input - end - end - end -end + def cache_bust(input) + puts "Processing asset: #{input}" + + # Get the file extension + ext = File.extname(input) + puts "File extension: #{ext}" + + # Define a list of supported asset types + supported_assets = %w[.css .js .png .jpg .jpeg .gif .svg .woff .woff2 .ttf .eot] + + # Check if the asset type is supported + if supported_assets.include?(ext) + puts "Asset type supported: #{ext}" + + # Compute the file hash + site_source = @context.registers[:site].source + puts "Site destination directory: #{site_source}" -Liquid::Template.register_filter(Jekyll::CacheBustFilter) + file_path = File.join(site_source, input) + puts "Constructed file path: #{file_path}" + if File.exist?(file_path) + puts "File exists: #{file_path}" + + file_content = File.read(file_path) + file_hash = Digest::MD5.hexdigest(file_content) + puts "File hash: #{file_hash}" + "#{input}?v=#{file_hash}" + else + if input == @context.registers[:site].config['main_style'] + puts "Digesting contents of _sass folder" + sass_folder_path = File.join(site_source, '_sass') + directory_hash = digest_directory_contents(sass_folder_path) + puts "Directory hash: #{directory_hash}" + "#{input}?v=#{directory_hash}" + else + puts "File does not exist: #{file_path}" + # Return the input unchanged if the file does not exist + input + end + end + else + puts "Asset type not supported: #{ext}" + # Return the input unchanged if the asset type is not supported + input + end + end + + private + + def digest_directory_contents(directory) + target_path = File.join(directory, '**', '*') + content = Dir[target_path].map { |f| File.read(f) unless File.directory?(f) }.join + Digest::MD5.hexdigest(content) + end + + end +end +Liquid::Template.register_filter(Jekyll::CacheBustFilter) \ No newline at end of file From 45b5264d2976f14f80216d991bde72b8687e8c2d Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 26 Jul 2024 13:23:31 +0700 Subject: [PATCH 4/4] Add jekyll-seo-tag to safe list --- docs/_config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/_config.yml b/docs/_config.yml index 7fe5222d1314..36eea67ad2de 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -23,3 +23,4 @@ plugins: whitelist: - jekyll-redirect-from + - jekyll-seo-tag