From e9fd650ba9c224330f88c4f4fde460d270a9fd29 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 16:08:21 -0300 Subject: [PATCH 1/8] fix: ignorar posts #13428 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit versiones de jekyll-locales menores a 0.2 dejan symlinks rotos en lugar de la colección _posts. con esto ignoramos la colección del todo, porque solo usamos las que están en idiomas. sutty obliga efectivamente a todos los sitios jekyll a usar jekyll-locales o al menos colocar los posts en un directorio de idiomas. una salvedad sería agregar esto en la configuración: ```yaml locales: - "posts" ``` --- config/initializers/core_extensions.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 1516a43a..abbdfda1 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -37,6 +37,19 @@ end # # TODO: Aplicar monkey patches en otro lado... module Jekyll + Configuration.class_eval do + # No agregar colecciones por defecto, solo las que digamos en base a + # los idiomas. Esto remueve la colección "posts". + # + # Las colecciones de idiomas son agregadas por Site. + # + # @see Site#configuration + # @return [Jekyll::Configuration] + def add_default_collections + self + end + end + Site.class_eval do def configure_theme self.theme = nil From e473de6a4ec515886b6fd172cc2ffa9d2abaafe4 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:31:40 -0300 Subject: [PATCH 2/8] fix: leer los archivos de datos correctamente #13428 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit los archivos de datos se leen con rutas relativas, lo que puede mezclar el cwd en usos concurrentes. depreca la dependencia en jekyll-data además! --- Gemfile | 2 +- Gemfile.lock | 3 -- .../jekyll/readers/data_reader_decorator.rb | 36 +++++++++++++++++++ app/models/site.rb | 4 +-- config/initializers/core_extensions.rb | 34 +++++++++++------- 5 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 app/lib/jekyll/readers/data_reader_decorator.rb diff --git a/Gemfile b/Gemfile index b2472035..5f1f6268 100644 --- a/Gemfile +++ b/Gemfile @@ -52,7 +52,7 @@ gem 'icalendar' gem 'inline_svg' gem 'httparty' gem 'safe_yaml' -gem 'jekyll', '~> 4.2' +gem 'jekyll', '~> 4.2.0' gem 'jekyll-data' gem 'jekyll-commonmark' gem 'jekyll-images' diff --git a/Gemfile.lock b/Gemfile.lock index 67ce13e2..951ae8c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -284,8 +284,6 @@ GEM jekyll-commonmark (1.3.2) commonmarker (~> 0.14, < 0.22) jekyll (>= 3.7, < 5.0) - jekyll-data (1.1.2) - jekyll (>= 3.3, < 5.0.0) jekyll-dotenv (0.2.0) dotenv (~> 2.7) jekyll (~> 4) @@ -644,7 +642,6 @@ DEPENDENCIES jbuilder (~> 2.5) jekyll (~> 4.2) jekyll-commonmark - jekyll-data jekyll-images jekyll-include-cache kaminari diff --git a/app/lib/jekyll/readers/data_reader_decorator.rb b/app/lib/jekyll/readers/data_reader_decorator.rb new file mode 100644 index 00000000..9fed7ac7 --- /dev/null +++ b/app/lib/jekyll/readers/data_reader_decorator.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Jekyll + module Readers + # Permite leer datos utilizando rutas absolutas. + # + # {Jekyll::DataReader} usa {Dir.chdir} con rutas relativas, lo que + # en nuestro uso provoca confusiones en el lector de datos. + # + # Con este módulo, podemos leer todos los archivos usando rutas + # absolutas, lo que nos permite reemplazar jekyll-data, que agregaba + # código duplicado. + module DataReaderDecorator + extend ActiveSupport::Concern + + included do + def read_data_to(dir, data) + return unless File.directory?(dir) && !@entry_filter.symlink?(dir) + + Dir.glob(File.join(dir, '*')).each do |path| + next if @entry_filter.symlink?(path) + + entry = Pathname.new(path).relative_path_from(dir).to_s + + if File.directory?(path) + read_data_to(path, data[sanitize_filename(entry)] = {}) + else + key = sanitize_filename(File.basename(entry, ".*")) + data[key] = read_data_file(path) + end + end + end + end + end + end +end diff --git a/app/models/site.rb b/app/models/site.rb index 24644b9c..a6e1c541 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -375,9 +375,7 @@ class Site < ApplicationRecord begin install_gems - Jekyll::Site.new(configuration).tap do |site| - site.reader = JekyllData::Reader.new(site) if site.theme - end + Jekyll::Site.new(configuration) end end diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index abbdfda1..861491ae 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -2,6 +2,7 @@ String.include CoreExtensions::String::StripTags Jekyll::Document.include CoreExtensions::Jekyll::Document::Path +Jekyll::DataReader.include Jekyll::Readers::DataReaderDecorator # Definir tags de Liquid que provienen de complementos para que siempre # devuelvan contenido vacío. @@ -70,9 +71,27 @@ module Jekyll # No necesitamos los archivos estáticos def retrieve_static_files(_, _); end - # Solo lee los datos + # Solo lee los datos, desde la plantilla y luego desde el sitio, + # usando rutas absolutas, para evitar el uso confuso de Dir.chdir. + # + # Reemplaza jekyll-data también! + # + # @return [Hash] def read_data - @site.data = DataReader.new(site).read(site.config['data_dir']) + @site.data = + begin + reader = DataReader.new(site) + theme_dir = site.in_theme_dir('_data') + data_dir = site.in_source_dir(site.config['data_dir']) + + if theme_dir + reader.read_data_to(theme_dir, reader.content) + reader.read_data_to(data_dir, reader.content) + reader.content + else + reader.read data_dir + end + end end # Lee los layouts @@ -174,14 +193,3 @@ module PgSearch end end end - -# JekyllData::Reader del plugin jekyll-data modifica Jekyll::Site#reader -# para también leer los datos que vienen en el theme. -module JekyllData - Reader.class_eval do - def read_data - super - read_theme_data - end - end -end From 1c294d450ea40b636b05e6ce48f5f27b461faffb Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:38:39 -0300 Subject: [PATCH 3/8] fix: deprecar Site#run_in_path #13428 ya no es necesario y Dir.chdir no es concurrente, con lo que nos ahorramos posibles bugs. --- app/models/site.rb | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index a6e1c541..fb790fe8 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -212,10 +212,8 @@ class Site < ApplicationRecord # Trae los datos del directorio _data dentro del sitio def data unless jekyll.data.present? - run_in_path do - jekyll.reader.read_data - jekyll.data['layouts'] ||= {} - end + jekyll.reader.read_data + jekyll.data['layouts'] ||= {} end jekyll.data @@ -225,9 +223,7 @@ class Site < ApplicationRecord # colecciones. def collections unless @read - run_in_path do - jekyll.reader.read_collections - end + jekyll.reader.read_collections @read = true end @@ -322,9 +318,7 @@ class Site < ApplicationRecord # # @return [Hash] def theme_layouts - run_in_path do - jekyll.reader.read_layouts - end + jekyll.reader.read_layouts end # Trae todos los valores disponibles para un campo @@ -550,10 +544,6 @@ class Site < ApplicationRecord I18n.t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.error')) end - def run_in_path(&block) - Dir.chdir path, &block - end - # Instala las gemas cuando es necesario: # # * El sitio existe From 622d3b47db784249c08408b9ea042902c77b6192 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:41:00 -0300 Subject: [PATCH 4/8] BREAKING CHANGE: deprecar Deploy#gems_dir por Site#bundle_path #13428 --- app/models/deploy.rb | 5 ----- app/models/deploy_local.rb | 4 ++-- app/models/site.rb | 5 +++++ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index a92708c0..573fe2f0 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -50,11 +50,6 @@ class Deploy < ApplicationRecord site.path end - # XXX: Ver DeployLocal#bundle - def gems_dir - @gems_dir ||= Rails.root.join('_storage', 'gems', site.name) - end - # Corre un comando, lo registra en la base de datos y devuelve el # estado. # diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 75ea8b1c..b8885509 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -55,7 +55,7 @@ class DeployLocal < Deploy # # @return [nil] def cleanup! - FileUtils.rm_rf(gems_dir) + FileUtils.rm_rf(site.bundle_path) FileUtils.rm_rf(yarn_cache_dir) FileUtils.rm_rf(File.join(site.path, 'node_modules')) FileUtils.rm_rf(File.join(site.path, '.sass-cache')) @@ -138,7 +138,7 @@ class DeployLocal < Deploy end def bundle(output: false) - run %(bundle install --deployment --no-cache --path="#{gems_dir}" --clean --without test development), output: output + run %(bundle install --deployment --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output end def jekyll_build(output: false) diff --git a/app/models/site.rb b/app/models/site.rb index fb790fe8..754f9df1 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -453,6 +453,11 @@ class Site < ApplicationRecord @docs = nil end + # @return [Pathname] + def bundle_path + @bundle_path ||= Rails.root.join('_storage', 'gems', name) + end + private # Asegurarse que el sitio tenga una llave privada From 310bd3171067012f909925a5560bda86cfd9e8e9 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:42:14 -0300 Subject: [PATCH 5/8] fix: no usar :send #13428 --- app/models/deploy_local.rb | 31 +++++++++++++++++-------------- app/models/site.rb | 5 +++-- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index b8885509..b5a15cfe 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -7,6 +7,18 @@ class DeployLocal < Deploy before_destroy :remove_destination! + def git_lfs(output: false) + run %(git lfs fetch), output: output + run %(git lfs checkout), output: output + end + + def bundle(output: false) + # XXX: Desde que ya no compartimos el directorio de gemas, tenemos + # que hacer limpieza después de instalar. + + run %(bundle install --deployment --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output + end + # Realizamos la construcción del sitio usando Jekyll y un entorno # limpio para no pasarle secretos # @@ -114,9 +126,11 @@ class DeployLocal < Deploy File.exist? pnpm_lock end - def git_lfs(output: false) - run %(git lfs fetch), output: output - run %(git lfs checkout), output: output + def pnpm(output: false) + return true unless pnpm_lock? + + run %(pnpm config set store-dir "#{pnpm_cache_dir}"), output: output + run 'pnpm install --production', output: output end def gem(output: false) @@ -130,17 +144,6 @@ class DeployLocal < Deploy run 'yarn install --production', output: output end - def pnpm(output: false) - return true unless pnpm_lock? - - run %(pnpm config set store-dir "#{pnpm_cache_dir}"), output: output - run 'pnpm install --production', output: output - end - - def bundle(output: false) - run %(bundle install --deployment --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output - end - def jekyll_build(output: false) run %(bundle exec jekyll build --trace --profile --destination "#{escaped_destination}"), output: output end diff --git a/app/models/site.rb b/app/models/site.rb index 754f9df1..fab16b58 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -558,10 +558,11 @@ class Site < ApplicationRecord def install_gems return unless persisted? - deploys.find_by_type('DeployLocal').send(:git_lfs) + deploy_local = deploys.find_by_type('DeployLocal') + deploy_local.git_lfs if !gem_dir? || gemfile_updated? || gemfile_lock_updated? - deploys.find_by_type('DeployLocal').send(:bundle) + deploy_local.bundle touch end end From 8d9328cd66dd2979ae0d10c1e94b90c1ed42a0ce Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:42:37 -0300 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20en=20algunos=20casos=20el=20director?= =?UTF-8?q?io=20exist=C3=ADa=20aunque=20vac=C3=ADo=20#13428?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/site.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index fab16b58..9bc2c7f4 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -561,15 +561,25 @@ class Site < ApplicationRecord deploy_local = deploys.find_by_type('DeployLocal') deploy_local.git_lfs - if !gem_dir? || gemfile_updated? || gemfile_lock_updated? + if !gems_installed? || gemfile_updated? || gemfile_lock_updated? deploy_local.bundle touch end end + def gem_path + @gem_path ||= + begin + ruby_version = Gem::Version.new(RUBY_VERSION) + ruby_version.canonical_segments[2] = 0 + + bundle_path.join('ruby', ruby_version.canonical_segments.join('.')) + end + end + # Detecta si el repositorio de gemas existe - def gem_dir? - Rails.root.join('_storage', 'gems', name).directory? + def gems_installed? + gem_path.directory? && !gem_path.empty? end # Detecta si el Gemfile fue modificado From 5d8c1556a8bbfb1e2762f2d233d4f14a97c1e8ea Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:43:02 -0300 Subject: [PATCH 7/8] fix: no fallar si no existe el Gemfile.lock #13428 --- app/models/site.rb | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 9bc2c7f4..924b6069 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -587,8 +587,15 @@ class Site < ApplicationRecord updated_at < File.mtime(File.join(path, 'Gemfile')) end + # @return [String] + def gemfile_lock_path + @gemfile_lock_path ||= File.join(path, 'Gemfile.lock') + end + # Detecta si el Gemfile.lock fue modificado def gemfile_lock_updated? - updated_at < File.mtime(File.join(path, 'Gemfile.lock')) + return false unless File.exist? gemfile_lock_path + + updated_at < File.mtime(gemfile_lock_path) end end From dc20e4c9ce3e583b8542abda342f97d1fa7ec224 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 13 May 2023 17:48:06 -0300 Subject: [PATCH 8/8] fix: permite instalar gemas por primera vez #13428 --- app/models/deploy_local.rb | 2 +- app/models/site.rb | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index b5a15cfe..4f8744f3 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -16,7 +16,7 @@ class DeployLocal < Deploy # XXX: Desde que ya no compartimos el directorio de gemas, tenemos # que hacer limpieza después de instalar. - run %(bundle install --deployment --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output + run %(bundle install #{'--deployment' if site.gemfile_lock_path?} --no-cache --path="#{site.bundle_path}" --clean --without test development), output: output end # Realizamos la construcción del sitio usando Jekyll y un entorno diff --git a/app/models/site.rb b/app/models/site.rb index 924b6069..786cb780 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -458,6 +458,10 @@ class Site < ApplicationRecord @bundle_path ||= Rails.root.join('_storage', 'gems', name) end + def gemfile_lock_path? + File.exist? gemfile_lock_path + end + private # Asegurarse que el sitio tenga una llave privada @@ -594,7 +598,7 @@ class Site < ApplicationRecord # Detecta si el Gemfile.lock fue modificado def gemfile_lock_updated? - return false unless File.exist? gemfile_lock_path + return false unless gemfile_lock_path? updated_at < File.mtime(gemfile_lock_path) end