Hello community, here is the log from the commit of package rubygem-zeitwerk for openSUSE:Factory checked in at 2020-04-27 23:41:05 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-zeitwerk (Old) and /work/SRC/openSUSE:Factory/.rubygem-zeitwerk.new.2738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-zeitwerk" Mon Apr 27 23:41:05 2020 rev:4 rq:798230 version:2.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-zeitwerk/rubygem-zeitwerk.changes 2019-12-14 12:23:58.519193924 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-zeitwerk.new.2738/rubygem-zeitwerk.changes 2020-04-27 23:41:15.383860339 +0200 @@ -1,0 +2,25 @@ +Mon Apr 27 11:38:16 UTC 2020 - Manuel Schnitzer <mschnit...@suse.com> + +- updated to version 2.3.0 + + * Adds support for collapsing directories. + + For example, if `booking/actions/create.rb` is meant to define `Booking::Create` + because the subdirectory `actions` is there only for organizational purposes, + you can tell Zeitwerk with `collapse`: + + ```ruby + loader.collapse("booking/actions") + ``` + + The method also accepts glob patterns to support standardized project structures: + + ```ruby + loader.collapse("*/actions") + ``` + + Please check the documentation for more details. + + * Eager loading is idempotent, but now you can eager load again after reloading. + +------------------------------------------------------------------- Old: ---- zeitwerk-2.2.2.gem New: ---- zeitwerk-2.3.0.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-zeitwerk.spec ++++++ --- /var/tmp/diff_new_pack.0TULDB/_old 2020-04-27 23:41:16.071861682 +0200 +++ /var/tmp/diff_new_pack.0TULDB/_new 2020-04-27 23:41:16.075861689 +0200 @@ -1,7 +1,7 @@ # # spec file for package rubygem-zeitwerk # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,7 +24,7 @@ # Name: rubygem-zeitwerk -Version: 2.2.2 +Version: 2.3.0 Release: 0 %define mod_name zeitwerk %define mod_full_name %{mod_name}-%{version} ++++++ zeitwerk-2.2.2.gem -> zeitwerk-2.3.0.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2019-11-29 17:02:42.000000000 +0100 +++ new/README.md 2020-03-03 20:52:17.000000000 +0100 @@ -12,6 +12,7 @@ - [File structure](#file-structure) - [Implicit namespaces](#implicit-namespaces) - [Explicit namespaces](#explicit-namespaces) + - [Collapsing directories](#collapsing-directories) - [Nested root directories](#nested-root-directories) - [Usage](#usage) - [Setup](#setup) @@ -165,6 +166,32 @@ An explicit namespace must be managed by one single loader. Loaders that reopen namespaces owned by other projects are responsible for loading their constants before setup. +<a id="markdown-collapsing-directories" name="collapsing-directories"></a> +### Collapsing directories + +Say some directories in a project exist for organizational purposes only, and you prefer not to have them as namespaces. For example, the `actions` subdirectory in the next example is not meant to represent a namespace, it is there only to group all actions related to bookings: + +``` +booking.rb -> Booking +booking/actions/create.rb -> Booking::Create +``` + +To make it work that way, configure Zeitwerk to collapse said directory: + +```ruby +loader.collapse("booking/actions") +``` + +This method accepts an arbitrary number of strings or `Pathname` objects, and also an array of them. + +You can pass directories and glob patterns. Glob patterns are expanded when they are added, and again on each reload. + +To illustrate usage of glob patterns, if `actions` in the example above is part of a standardized structure, you could use a wildcard: + +```ruby +loader.collapse("*/actions") +``` + <a id="markdown-nested-root-directories" name="nested-root-directories"></a> ### Nested root directories Binary files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/zeitwerk/loader.rb new/lib/zeitwerk/loader.rb --- old/lib/zeitwerk/loader.rb 2019-11-29 17:02:42.000000000 +0100 +++ new/lib/zeitwerk/loader.rb 2020-03-03 20:52:17.000000000 +0100 @@ -39,7 +39,7 @@ # @return [<String>] attr_reader :preloads - # Absolute paths of files, directories, of glob patterns to be totally + # Absolute paths of files, directories, or glob patterns to be totally # ignored. # # @private @@ -54,6 +54,19 @@ # @return [Set<String>] attr_reader :ignored_paths + # Absolute paths of directories or glob patterns to be collapsed. + # + # @private + # @return [Set<String>] + attr_reader :collapse_glob_patterns + + # The actual collection of absolute directory names at the time the collapse + # glob patterns were expanded. Computed on setup, and recomputed on reload. + # + # @private + # @return [Set<String>] + attr_reader :collapse_dirs + # Maps real absolute paths for which an autoload has been set ---and not # executed--- to their corresponding parent class or module and constant # name. @@ -131,15 +144,17 @@ @inflector = Inflector.new @logger = self.class.default_logger - @root_dirs = {} - @preloads = [] - @ignored_glob_patterns = Set.new - @ignored_paths = Set.new - @autoloads = {} - @autoloaded_dirs = [] - @to_unload = {} - @lazy_subdirs = {} - @eager_load_exclusions = Set.new + @root_dirs = {} + @preloads = [] + @ignored_glob_patterns = Set.new + @ignored_paths = Set.new + @collapse_glob_patterns = Set.new + @collapse_dirs = Set.new + @autoloads = {} + @autoloaded_dirs = [] + @to_unload = {} + @lazy_subdirs = {} + @eager_load_exclusions = Set.new # TODO: find a better name for these mutexes. @mutex = Mutex.new @@ -154,6 +169,7 @@ # Sets a tag for the loader, useful for logging. # + # @param tag [#to_s] # @return [void] def tag=(tag) @tag = tag.to_s @@ -233,6 +249,18 @@ end end + # Configure directories or glob patterns to be collapsed. + # + # @param paths [<String, Pathname, <String, Pathname>>] + # @return [void] + def collapse(*glob_patterns) + glob_patterns = expand_paths(glob_patterns) + mutex.synchronize do + collapse_glob_patterns.merge(glob_patterns) + collapse_dirs.merge(expand_glob_patterns(glob_patterns)) + end + end + # Sets autoloads in the root namespace and preloads files, if any. # # @return [void] @@ -306,7 +334,8 @@ Registry.on_unload(self) ExplicitNamespace.unregister(self) - @setup = false + @setup = false + @eager_loaded = false end end @@ -322,6 +351,7 @@ if reloading_enabled? unload recompute_ignored_paths + recompute_collapse_dirs setup else raise ReloadingDisabledError, "can't reload, please call loader.enable_reloading before setup" @@ -351,8 +381,12 @@ cref[0].const_get(cref[1], false) end elsif dir?(abspath) && !root_dirs.key?(abspath) - cname = inflector.camelize(basename, abspath) - queue << [namespace.const_get(cname, false), abspath] + if collapse_dirs.member?(abspath) + queue << [namespace, abspath] + else + cname = inflector.camelize(basename, abspath) + queue << [namespace.const_get(cname, false), abspath] + end end end end @@ -476,7 +510,7 @@ ls(dir) do |basename, abspath| begin if ruby?(basename) - basename.slice!(-3, 3) + basename[-3..-1] = '' cname = inflector.camelize(basename, abspath).to_sym autoload_file(parent, cname, abspath) elsif dir?(abspath) @@ -488,7 +522,11 @@ # it counts only as root. The guard checks that. unless root_dirs.key?(abspath) cname = inflector.camelize(basename, abspath).to_sym - autoload_subdir(parent, cname, abspath) + if collapse_dirs.member?(abspath) + set_autoloads_in_dir(abspath, parent) + else + autoload_subdir(parent, cname, abspath) + end end end rescue ::NameError => error @@ -717,6 +755,11 @@ ignored_paths.replace(expand_glob_patterns(ignored_glob_patterns)) end + # @return [void] + def recompute_collapse_dirs + collapse_dirs.replace(expand_glob_patterns(collapse_glob_patterns)) + end + # @param message [String] # @return [void] def log(message) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/zeitwerk/version.rb new/lib/zeitwerk/version.rb --- old/lib/zeitwerk/version.rb 2019-11-29 17:02:42.000000000 +0100 +++ new/lib/zeitwerk/version.rb 2020-03-03 20:52:17.000000000 +0100 @@ -1,5 +1,5 @@ # frozen_string_literal: true module Zeitwerk - VERSION = "2.2.2" + VERSION = "2.3.0" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2019-11-29 17:02:42.000000000 +0100 +++ new/metadata 2020-03-03 20:52:17.000000000 +0100 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: zeitwerk version: !ruby/object:Gem::Version - version: 2.2.2 + version: 2.3.0 platform: ruby authors: - Xavier Noria autorequire: bindir: bin cert_chain: [] -date: 2019-11-29 00:00:00.000000000 Z +date: 2020-03-03 00:00:00.000000000 Z dependencies: [] description: |2 Zeitwerk implements constant autoloading with Ruby semantics. Each gem