From c44070fdfb47f6094c4c013cce92951ae64db2ec Mon Sep 17 00:00:00 2001 From: synesissoftware Date: Thu, 27 Aug 2026 20:07:42 +1000 Subject: [PATCH 1/2] 0.2.4 (#4) * **run_all_unit_tests.sh** : ~ updated to latest (from https://github.com/synesissoftware/misc-dev-scripts) * boilerplate: markdown files * boilerplate: .gitattributes * boilerplate: LICENSE * boilerplate: .vscode/settings.json * boilerplate: .vimrc * boilerplate: build_gem.cmd, build_gem.sh, generate_rdoc.cmd, generate_rdoc.sh * boilerplate: LICENSE * bolierplate: updating Gemfile * boilerplate: placeholder markdown files * boilerplate: .gitignore * version dependencies * boilerplate: .ruby-version-exclusions * Add canonical AUTHORS, FAQ, NEWS, and TODO markdown skeletons * Complete CHANGES.md through early 0.0.x releases * Add ruby.yml CI badge and switch Gemfile to gemspec * chore: dependencies * gemspec updates * chore: AUTHORS.md * fix: gemspec metadata * added/updated Rakefile * chore: CONTRIBUTING.md, INSTALL.md, SECURITY.md * chore: rake in Gemfile * fix: Add frozen lib/ strings and standardise Ruby gem boilerplate * standard CI for all projects * standard .editorconfig and dependabot for all projects * TODO.md * examples * CHANGES.md * NEWS.md * README.md * spacing * 0.2.4 * TODO.md --- .github/workflows/ruby.yml | 21 ++++- .gitignore | 9 +- CHANGES.md | 13 +++ EXAMPLES.md | 6 +- FAQ.md | 1 - Gemfile | 7 ++ Gemfile.lock | 20 ---- NEWS.md | 1 + README.md | 62 +++++++++++- TODO.md | 11 ++- lib/libpath/constants/unix.rb | 2 +- lib/libpath/constants/windows.rb | 2 +- .../exceptions/libpath_base_exception.rb | 2 +- .../exceptions/malformed_name_exception.rb | 2 +- lib/libpath/form/unix.rb | 2 +- lib/libpath/form/windows.rb | 2 +- lib/libpath/internal_/unix/form.rb | 1 + lib/libpath/internal_/windows/form.rb | 3 +- lib/libpath/path/unix.rb | 2 +- lib/libpath/path/windows.rb | 2 +- lib/libpath/util/unix.rb | 2 +- lib/libpath/util/windows.rb | 4 +- lib/libpath/version.rb | 6 +- libpath.gemspec => libpath-ruby.gemspec | 34 +++++-- run_all_unit_tests.sh | 94 ++++++++++++------- 25 files changed, 216 insertions(+), 95 deletions(-) delete mode 100644 Gemfile.lock rename libpath.gemspec => libpath-ruby.gemspec (62%) diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index f2e4fd2..6673261 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -7,7 +7,7 @@ # # Created: 15th August 2026 -# Updated: 15th August 2026 +# Updated: 19th August 2026 # name: Ruby @@ -70,13 +70,20 @@ jobs: uses: actions/checkout@v4 - name: Remove Gemfile.lock + shell: bash run: rm -f Gemfile.lock - name: Set up Ruby v${{ matrix.ruby-version }} uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby-version }} - bundler-cache: true # runs 'bundle install' and caches installed gems automatically + # Bundler 4 honours Gemfile `lockfile false`, so no Gemfile.lock + # is written. bundler-cache cats that file after `bundle lock` + # and fails on Windows 3.2+ (setup-ruby installs Bundler ~> 4). + bundler-cache: false + + - name: Install gems + run: bundle install - name: Show Ruby version run: ruby -v @@ -87,7 +94,7 @@ jobs: - name: Gem build and install smoke shell: bash run: | - gem build libpath.gemspec + gem build libpath-ruby.gemspec gem install --local libpath-ruby-*.gem ruby -e "require 'libpath/version'; abort('VERSION missing') unless defined?(LibPath::VERSION); puts LibPath::VERSION" @@ -102,13 +109,17 @@ jobs: uses: actions/checkout@v4 - name: Remove Gemfile.lock + shell: bash run: rm -f Gemfile.lock - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.3' - bundler-cache: true + ruby-version: '3.4' + bundler-cache: false + + - name: Install gems + run: bundle install - name: Show Ruby version run: ruby -v diff --git a/.gitignore b/.gitignore index 0d510c3..ce639ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,13 @@ # directories (by name) -/.bzr/ /.bundle/ +/.bzr/ /.config/ /.svn/ +/.vscode/ /.yardoc/ +/_build/ /_yardoc/ /InstalledFiles/ @@ -23,8 +25,10 @@ /tmp/ /vendor/bundle/ + # directories (by pattern) + # files (by name) .DS_Store @@ -32,8 +36,11 @@ .ruby-version .rvmrc +Gemfile.lock + /spec/examples.txt + # files (by pattern) *~ diff --git a/CHANGES.md b/CHANGES.md index 8d00896..365837b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,19 @@ # libpath.Ruby - Changes +## 0.2.4 - 19th August 2026 + +* renamed **libpath.gemspec** to **libpath-ruby.gemspec** so the filename stem matches `spec.name`; +* **libpath-ruby.gemspec**: `required_ruby_version` is the range `>= 2.0`; **Gemfile.lock** and **.ruby-version** excluded from `spec.files`; `spec.summary` matches the README tagline; packaged **AUTHORS**, **CHANGES**, **CONTRIBUTING**, **EXAMPLES**, **FAQ**, **INSTALL**, **NEWS**, **SECURITY**, **TODO**; +* **Gemfile** sets `lockfile false` when Bundler supports it; stop tracking **Gemfile.lock**; +* CI uses `bundler-cache: false` and explicit `bundle install`; **Warnings** job on Ruby **3.4**; `gem build libpath-ruby.gemspec`; +* updated **run_all_unit_tests.sh** (from https://github.com/synesissoftware/misc-dev-scripts) to skip **tput** when **$TERM** is unset or stdout is not a TTY; +* library source **Home:** URLs now use `https`; +* **README.md**: tagline before badges; canonical badge row; **Dependencies** (Efferent / Afferent); related projects; License → `./LICENSE`; +* **EXAMPLES.md** example links are repo-relative (`./examples/…`); +* `elide_redundant_path_name_separators!` is freeze-safe (Ruby 3.4 `FrozenError` on a frozen remainder, e.g. malformed UNC); + + ## 0.2.3 - 15th August 2026 * added `# frozen_string_literal: true` to all **lib/** sources; diff --git a/EXAMPLES.md b/EXAMPLES.md index f62248b..eb379f2 100644 --- a/EXAMPLES.md +++ b/EXAMPLES.md @@ -1,8 +1,8 @@ # libpath.Ruby - Examples -| Name | Source & Description | Summary | -| ------------------ | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ | -| **path_from_arg0** | [examples/path_from_arg0.rb](/examples/path_from_arg0.rb)
[examples/path_from_arg0.md](/examples/path_from_arg0.md) | Simple example illustrating creation of an instance of `LibPath::Path::ParsedPath`, and obtaining its attributes | +|Name|Source & Description|Summary| +|---|---|---| +|**path_from_arg0**|[examples/path_from_arg0.rb](./examples/path_from_arg0.rb)
[examples/path_from_arg0.md](./examples/path_from_arg0.md)|Simple example illustrating creation of an instance of `LibPath::Path::ParsedPath`, and obtaining its attributes| diff --git a/FAQ.md b/FAQ.md index 113fbdc..c07c887 100644 --- a/FAQ.md +++ b/FAQ.md @@ -24,5 +24,4 @@ gem install libpath-ruby See [README.md](./README.md) for usage. - diff --git a/Gemfile b/Gemfile index 29f6d2e..79965e8 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,13 @@ source "https://rubygems.org" +# Suppress lockfile on Bundler 4+ (gem: do not pin the graph). No-op on +# Bundler that lacks the DSL (Ruby 2.x CI). Do not combine with +# ruby/setup-ruby `bundler-cache: true` — that action cats Gemfile.lock +# after `bundle lock` and fails when no file is written (Windows 3.2+, +# where setup-ruby installs Bundler ~> 4). +lockfile false if respond_to?(:lockfile) + gemspec # rake 13 requires Ruby >= 2.3 diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 4389314..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,20 +0,0 @@ -PATH - remote: . - specs: - libpath-ruby (0.2.2.3) - -GEM - remote: https://rubygems.org/ - specs: - xqsr3 (0.39.5) - -PLATFORMS - arm64-darwin-25 - ruby - -DEPENDENCIES - libpath-ruby! - xqsr3 (>= 0.21.1, < 1.0) - -BUNDLED WITH - 2.6.9 diff --git a/NEWS.md b/NEWS.md index 0338e2e..5b4c068 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ | Date | News Item | | ----------------- | -------------------------------------------------------------------------------------------- | +| 19th August 2026 | [**libpath.Ruby** 0.2.4](https://github.com/synesissoftware/libpath.Ruby/releases/tag/0.2.4) | | 15th August 2026 | [**libpath.Ruby** 0.2.3](https://github.com/synesissoftware/libpath.Ruby/releases/tag/0.2.3) | | 13th April 2024 | [**libpath.Ruby** 0.2.2.3](https://github.com/synesissoftware/libpath.Ruby/releases/tag/0.2.2.3) | | 7th April 2024 | **libpath.Ruby** 0.2.2.2 released | diff --git a/README.md b/README.md index 5b9f664..cb7b903 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,11 @@ # libpath.Ruby -**libpath**, for Ruby +Path parsing library, for Ruby +![Language](https://img.shields.io/badge/Ruby-CC342D?style=flat&logo=ruby&logoColor=white) +[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) [![Gem Version](https://badge.fury.io/rb/libpath-ruby.svg)](https://badge.fury.io/rb/libpath-ruby) +[![Last Commit](https://img.shields.io/github/last-commit/synesissoftware/libpath.Ruby)](https://github.com/synesissoftware/libpath.Ruby/commits/master) [![Ruby](https://github.com/synesissoftware/libpath.Ruby/actions/workflows/ruby.yml/badge.svg)](https://github.com/synesissoftware/libpath.Ruby/actions/workflows/ruby.yml) @@ -15,6 +18,13 @@ - [Project Information](#project-information) - [Where to get help](#where-to-get-help) - [Contribution guidelines](#contribution-guidelines) + - [Dependencies](#dependencies) + - [Efferent (fan-out)](#efferent-fan-out) + - [Runtime Dependencies (aka "Normal Dependencies")](#runtime-dependencies-aka-normal-dependencies) + - [Development Dependencies](#development-dependencies) + - [Afferent (fan-in)](#afferent-fan-in) + - [Runtime dependents](#runtime-dependents) + - [Development dependents](#development-dependents) - [Related projects](#related-projects) - [License](#license) @@ -23,6 +33,8 @@ **libpath** is a path-parsing and utility library. It is concerned entirely with paths, as opposed to file-system entities. +The first **libpath** library was a C library with a C++ wrapper. There have been several implementations in other languages. **libpath.Ruby** is the Ruby version. + ## Installation @@ -40,6 +52,7 @@ Use via **require**, as in: require 'libpath' ``` + ## Components The main components of **libpath.Ruby** are: @@ -71,17 +84,56 @@ Examples are provided in the ```examples``` directory, along with a markdown des Defect reports, feature requests, and pull requests are welcome on https://github.com/synesissoftware/libpath.Ruby. +### Dependencies + + +#### Efferent (fan-out) + +Libraries upon which **libpath.Ruby** depends: + + +##### Runtime Dependencies (aka "Normal Dependencies") + +* \; + + +##### Development Dependencies + +* [**rake**](https://rubygems.org/gems/rake); +* [**test-unit**](https://rubygems.org/gems/test-unit); +* [**xqsr3**](https://github.com/synesissoftware/xqsr3); + + +#### Afferent (fan-in) + +Projects that depend on **libpath.Ruby**: + + +##### Runtime dependents + +* \; + +> **NOTE**: **[recls.Ruby](https://github.com/synesissoftware/recls.Ruby)** version 3+ is planned to depend on **libpath.Ruby** (it currently has its own path-parsing logic). + + +##### Development dependents + +* \; + + ### Related projects -**libpath.Ruby** is based on the [C/C++ libpath library](https://github.com/synesissoftware/libpath), which itself was prompted by a request on the [STLSoft](https://github.com/synesissoftware/STLSoft-1.10) project by my friend and esteemed programmer [Adi Shavit](https://github.com/adishavit). +* [**libpath**](https://github.com/synesissoftware/libpath) (**C**/**C++**); +* [**libpath.Go**](https://github.com/synesissoftware/libpath.Go); +* [**libpath.Python**](https://github.com/synesissoftware/libpath.Python); +* [**libpath.Rust**](https://github.com/synesissoftware/libpath.Rust); -**libpath.Ruby** will be used in **version 3+** of the **[recls.Ruby](https://github.com/synesissoftware/recls.Ruby)** library, which currently has its own path-parsing logic. +**libpath.Ruby** is based on the C/C++ **libpath** library, which itself was prompted by a request on the [STLSoft](https://github.com/synesissoftware/STLSoft-1.10) project by my friend and esteemed programmer [Adi Shavit](https://github.com/adishavit). ### License -**libpath.Ruby** is released under the 3-clause BSD license. See LICENSE for details. +**libpath.Ruby** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) for details. - diff --git a/TODO.md b/TODO.md index 58f8aa2..59610f4 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,7 @@ ## Functional improvements -* \ +* [ ] quiet Ruby 3.4+ `literal string will be frozen in the future` warnings from `gsub!` in **lib/libpath/internal_/windows/form.rb** (tests already pass under `-W`); ## Performance improvements @@ -13,7 +13,14 @@ ## Packaging improvements -* [ ] Rename gemspec so the filename stem matches `spec.name` (`libpath.gemspec` → **libpath-ruby.gemspec**); +* [x] ~~~rename gemspec so the filename stem matches `spec.name` (`libpath.gemspec` → **libpath-ruby.gemspec**)~~~; +* [x] ~~~obtain a **run_all_unit_tests.sh** (from **misc-dev-scripts**) that skips `tput` when `$TERM` is unset or stdout is not a TTY (CI: `tput: No value for $TERM and no -T specified`)~~~; +* [x] ~~~**Gemfile** `lockfile false`; stop tracking **Gemfile.lock**; CI `bundler-cache: false`~~~; +* [x] ~~~gemspec polish: README tagline as `spec.summary`, package docs, exclude **Gemfile.lock** / **.ruby-version**~~~; +* [x] ~~~README canonical structure (tagline before badges; **Dependencies**; CI badge → **ruby.yml**)~~~; +* [x] ~~~after the packaging/boilerplate/CI baseline: bump **VERSION** and align **CHANGES**/**NEWS**~~~; +* [ ] **git rm** **Gemfile.lock** when committing this lift (deleted in the work tree and gitignored; still in HEAD); +* [ ] this lift is on **bp-2**, which is not in CI `on.push.branches` (gold seven-name set); use a PR (unfiltered `pull_request:`) or merge to a listed branch to run push CI; diff --git a/lib/libpath/constants/unix.rb b/lib/libpath/constants/unix.rb index 7c4b480..4b67a20 100644 --- a/lib/libpath/constants/unix.rb +++ b/lib/libpath/constants/unix.rb @@ -7,7 +7,7 @@ # Created: 29th January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/constants/windows.rb b/lib/libpath/constants/windows.rb index 9814fed..52d2417 100644 --- a/lib/libpath/constants/windows.rb +++ b/lib/libpath/constants/windows.rb @@ -7,7 +7,7 @@ # Created: 29th January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/exceptions/libpath_base_exception.rb b/lib/libpath/exceptions/libpath_base_exception.rb index 81ec22a..5196327 100644 --- a/lib/libpath/exceptions/libpath_base_exception.rb +++ b/lib/libpath/exceptions/libpath_base_exception.rb @@ -7,7 +7,7 @@ # Created: 30th January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/exceptions/malformed_name_exception.rb b/lib/libpath/exceptions/malformed_name_exception.rb index ce72728..81e1c9a 100644 --- a/lib/libpath/exceptions/malformed_name_exception.rb +++ b/lib/libpath/exceptions/malformed_name_exception.rb @@ -7,7 +7,7 @@ # Created: 30th January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/form/unix.rb b/lib/libpath/form/unix.rb index dc0fc3e..fed5227 100644 --- a/lib/libpath/form/unix.rb +++ b/lib/libpath/form/unix.rb @@ -7,7 +7,7 @@ # Created: 8th January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/form/windows.rb b/lib/libpath/form/windows.rb index 83404e0..999dc21 100644 --- a/lib/libpath/form/windows.rb +++ b/lib/libpath/form/windows.rb @@ -7,7 +7,7 @@ # Created: 8th January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/internal_/unix/form.rb b/lib/libpath/internal_/unix/form.rb index 51db63e..69d1b0b 100644 --- a/lib/libpath/internal_/unix/form.rb +++ b/lib/libpath/internal_/unix/form.rb @@ -75,6 +75,7 @@ def self.elide_redundant_path_name_separators s # :nodoc: # @!visibility private def self.elide_redundant_path_name_separators! s # :nodoc: + s = s.dup if s.frozen? s.gsub!(/\/\/+/, '/') s diff --git a/lib/libpath/internal_/windows/form.rb b/lib/libpath/internal_/windows/form.rb index b385920..9c9fa96 100644 --- a/lib/libpath/internal_/windows/form.rb +++ b/lib/libpath/internal_/windows/form.rb @@ -81,6 +81,7 @@ def self.elide_redundant_path_name_separators s # :nodoc: # @!visibility private def self.elide_redundant_path_name_separators! s # :nodoc: + s = s.dup if s.frozen? s.gsub!(/[\\\/]{2,}/, '\\') s @@ -208,7 +209,7 @@ def self.split_path s # :nodoc: f1_volume, rem, frm = self.get_windows_volume s - self.elide_redundant_path_name_separators! rem + rem = self.elide_redundant_path_name_separators! rem f1_volume.define_singleton_method(:form) { frm } if f1_volume diff --git a/lib/libpath/path/unix.rb b/lib/libpath/path/unix.rb index 8997069..6e79a93 100644 --- a/lib/libpath/path/unix.rb +++ b/lib/libpath/path/unix.rb @@ -7,7 +7,7 @@ # Created: 21st January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/path/windows.rb b/lib/libpath/path/windows.rb index 23cb79b..ad937fe 100644 --- a/lib/libpath/path/windows.rb +++ b/lib/libpath/path/windows.rb @@ -7,7 +7,7 @@ # Created: 21st January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/util/unix.rb b/lib/libpath/util/unix.rb index 50359b2..5104ded 100644 --- a/lib/libpath/util/unix.rb +++ b/lib/libpath/util/unix.rb @@ -7,7 +7,7 @@ # Created: 14th January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # diff --git a/lib/libpath/util/windows.rb b/lib/libpath/util/windows.rb index cf0470f..2843d66 100644 --- a/lib/libpath/util/windows.rb +++ b/lib/libpath/util/windows.rb @@ -7,7 +7,7 @@ # Created: 10th January 2019 # Updated: 15th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # @@ -492,7 +492,7 @@ def make_path_absolute path, **options vol, rem, _ = _Internal_Windows_Form.get_windows_volume r - _Internal_Windows_Form.elide_redundant_path_name_separators! rem + rem = _Internal_Windows_Form.elide_redundant_path_name_separators! rem r = "#{vol}#{rem}" end diff --git a/lib/libpath/version.rb b/lib/libpath/version.rb index 8467ea5..33f1c86 100644 --- a/lib/libpath/version.rb +++ b/lib/libpath/version.rb @@ -5,9 +5,9 @@ # Purpose: Version for libpath.Ruby library # # Created: 8th January 2019 -# Updated: 15th August 2026 +# Updated: 19th August 2026 # -# Home: http://github.com/synesissoftware/libpath.Ruby +# Home: https://github.com/synesissoftware/libpath.Ruby # # Author: Matthew Wilson # @@ -51,7 +51,7 @@ module LibPath # Current version of the libpath.Ruby library - VERSION = '0.2.3' + VERSION = '0.2.4' private # @!visibility private diff --git a/libpath.gemspec b/libpath-ruby.gemspec similarity index 62% rename from libpath.gemspec rename to libpath-ruby.gemspec index ef1301c..85e5f4d 100644 --- a/libpath.gemspec +++ b/libpath-ruby.gemspec @@ -1,10 +1,10 @@ # ######################################################################## # -# File: libpath.gemspec +# File: libpath-ruby.gemspec # # Purpose: Gemspec for libpath.Ruby library # # Created: 8th January 2019 -# Updated: 15th August 2026 +# Updated: 19th August 2026 # # ######################################################################## # @@ -17,10 +17,12 @@ require 'libpath/version' Gem::Specification.new do |spec| spec.name = 'libpath-ruby' + spec.summary = 'Path parsing library, for Ruby' spec.version = LibPath::VERSION - spec.summary = 'libpath.Ruby' spec.description = <= 2.0' ] spec.metadata = { 'bug_tracker_uri' => 'https://github.com/synesissoftware/libpath.Ruby/issues', @@ -41,9 +43,27 @@ END_DESC 'source_code_uri' => 'https://github.com/synesissoftware/libpath.Ruby', } - spec.add_development_dependency "xqsr3", [ '>= 0.39.5', '< 1.0' ] + spec.files = Dir[ + 'Rakefile', + '{bin,examples,lib,man,spec,test}/**/*', + 'AUTHORS*', + 'CHANGES*', + 'CONTRIBUTING*', + 'EXAMPLES*', + 'FAQ*', + 'INSTALL*', + 'LICENSE*', + 'NEWS*', + 'README*', + 'SECURITY*', + 'TODO*', + ] & `git ls-files -z`.split("\0") + spec.files -= [ + '.ruby-version', + 'Gemfile.lock', + ] - spec.files = Dir[ 'Rakefile', '{bin,examples,lib,man,spec,test}/**/*', 'README*', 'LICENSE*' ] & `git ls-files -z`.split("\0") + spec.add_development_dependency "xqsr3", [ '>= 0.39.5', '< 1.0' ] end diff --git a/run_all_unit_tests.sh b/run_all_unit_tests.sh index 6aea55b..0a05634 100755 --- a/run_all_unit_tests.sh +++ b/run_all_unit_tests.sh @@ -8,7 +8,7 @@ # executing each rbenv version # # Created: 9th June 2011 -# Updated: 12th August 2026 +# Updated: 19th August 2026 # # Copyright (c) Matthew Wilson, 2011-2026 # All rights reserved @@ -58,18 +58,20 @@ Basename="$(basename "$Source")" # colours -if command -v tput > /dev/null; then +SisClr_Blue=${FG_BLUE:-} +SisClr_Red=${FG_RED:-} +SisClr_Bold=${FD_BOLD:-} +SisClr_None=${FD_NONE:-} - SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} - SisClr_Red=${FG_RED:-$(tput setaf 1)} - SisClr_Bold=${FD_BOLD:-$(tput bold)} - SisClr_None=${FD_NONE:-$(tput sgr0)} -else +if [ -n "${TERM:-}" ] && [ -t 1 ] && command -v tput >/dev/null 2>&1; then + + if tput sgr0 >/dev/null 2>&1; then - SisClr_Blue= - SisClr_Red= - SisClr_Bold= - SisClr_None= + SisClr_Blue=${FG_BLUE:-$(tput setaf 4)} + SisClr_Red=${FG_RED:-$(tput setaf 1)} + SisClr_Bold=${FD_BOLD:-$(tput bold)} + SisClr_None=${FD_NONE:-$(tput sgr0)} + fi fi @@ -115,19 +117,19 @@ if [ ! -z "$RunRbEnvAllVersions" ]; then if ! command -v rbenv > /dev/null; then - >&2 echo "$0: ${SisClr_Red}${SisClr_Bold}rbenv${SisClr_None} not detected" + >&2 echo "$0: ${SisClr_Red}${SisClr_Bold}rbenv${SisClr_None} not detected" - exit 1 + exit 1 fi exclusions=() if [ -e "$ProjectDir/.ruby-version-exclusions" ]; then - exclusion_lines=`cat "$ProjectDir/.ruby-version-exclusions"` - for line in $exclusion_lines; do + exclusion_lines=`cat "$ProjectDir/.ruby-version-exclusions"` + for line in $exclusion_lines; do - exclusions+=("$line") - done + exclusions+=("$line") + done fi echo "executing command line '${SisClr_Blue}${SisClr_Bold}$0 ${ForwardArgs[*]}${SisClr_None}' with all Ruby versions ..." @@ -138,11 +140,20 @@ if [ ! -z "$RunRbEnvAllVersions" ]; then current=$(tr -d '[:space:]' < "$ProjectDir/.ruby-version") fi + if ! version_output=$(rbenv versions --bare); then + + >&2 echo "$0: ${SisClr_Red}${SisClr_Bold}failed to enumerate Ruby versions via rbenv${SisClr_None}" + exit 1 + fi + versions=() - while IFS= read -r line; do + if [ -n "$version_output" ]; then - versions+=("$line") - done < <(rbenv versions --bare) + while IFS= read -r line; do + + versions+=("$line") + done <<< "$version_output" + fi echo "versions: ${SisClr_Blue}${SisClr_Bold}${versions[*]}${SisClr_None}; skipped versions: ${SisClr_Blue}${SisClr_Bold}${exclusions[*]}${SisClr_None}; current version: ${SisClr_Blue}${SisClr_Bold}${current:-(none)}${SisClr_None}" @@ -151,32 +162,32 @@ if [ ! -z "$RunRbEnvAllVersions" ]; then for version in "${versions[@]}" do - echo + echo - skip= + skip= - for exclusion in "${exclusions[@]}"; do + for exclusion in "${exclusions[@]}"; do - if [[ "$exclusion" == "$version" ]]; then + if [[ "$exclusion" == "$version" ]]; then - skip=1 - fi - done + skip=1 + fi + done - if [ "$skip" != "" ]; then + if [ "$skip" != "" ]; then - echo "skipping Ruby version ${SisClr_Blue}${SisClr_Bold}$version${SisClr_None}:" - else + echo "skipping Ruby version ${SisClr_Blue}${SisClr_Bold}$version${SisClr_None}:" + else - echo "processing Ruby version ${SisClr_Blue}${SisClr_Bold}$version${SisClr_None}:" + echo "processing Ruby version ${SisClr_Blue}${SisClr_Bold}$version${SisClr_None}:" - echo -e "\texecuting command line 'RBENV_VERSION=$version $0 ${ForwardArgs[*]}' with Ruby version $version ..." + echo -e "\texecuting command line 'RBENV_VERSION=$version $0 ${ForwardArgs[*]}' with Ruby version $version ..." - if ! RBENV_VERSION="$version" "$0" "${ForwardArgs[@]}"; then + if ! RBENV_VERSION="$version" "$0" "${ForwardArgs[@]}"; then - result=1 + result=1 + fi fi - fi done exit $result @@ -275,13 +286,24 @@ else result=0 + test_files=$(mktemp "${TMPDIR:-/tmp}/run_all_unit_tests.XXXXXX") || { + >&2 echo "$0: ${SisClr_Red}${SisClr_Bold}failed to create temporary file for test discovery${SisClr_None}" + exit 1 + } + trap 'rm -f "$test_files"' EXIT + + if ! find "$ProjectDir" -name 'tc_*.rb' -print0 > "$test_files"; then + >&2 echo "$0: ${SisClr_Red}${SisClr_Bold}failed to discover test files${SisClr_None}" + exit 1 + fi + while IFS= read -r -d '' testfile; do if ! ruby $DebugFlag $WarningsFlag "$testfile"; then result=1 fi - done < <(find "$ProjectDir" -name 'tc_*.rb' -print0) + done < "$test_files" exit $result fi From e07848c93d5812df8abcb0afa35f020baf873155 Mon Sep 17 00:00:00 2001 From: Matt Wilson Date: Thu, 27 Aug 2026 20:25:16 +1000 Subject: [PATCH 2/2] 0.2.4 --- CHANGES.md | 3 ++- NEWS.md | 2 +- lib/libpath/internal_/unix/form.rb | 7 ++----- lib/libpath/internal_/windows/form.rb | 9 +++------ lib/libpath/util/windows.rb | 2 +- lib/libpath/version.rb | 2 +- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 365837b..a2859d4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,7 @@ # libpath.Ruby - Changes -## 0.2.4 - 19th August 2026 +## 0.2.4 - 27th August 2026 * renamed **libpath.gemspec** to **libpath-ruby.gemspec** so the filename stem matches `spec.name`; * **libpath-ruby.gemspec**: `required_ruby_version` is the range `>= 2.0`; **Gemfile.lock** and **.ruby-version** excluded from `spec.files`; `spec.summary` matches the README tagline; packaged **AUTHORS**, **CHANGES**, **CONTRIBUTING**, **EXAMPLES**, **FAQ**, **INSTALL**, **NEWS**, **SECURITY**, **TODO**; @@ -9,6 +9,7 @@ * CI uses `bundler-cache: false` and explicit `bundle install`; **Warnings** job on Ruby **3.4**; `gem build libpath-ruby.gemspec`; * updated **run_all_unit_tests.sh** (from https://github.com/synesissoftware/misc-dev-scripts) to skip **tput** when **$TERM** is unset or stdout is not a TTY; * library source **Home:** URLs now use `https`; +* workarounds for avoiding potentially modifying frozen strings; * **README.md**: tagline before badges; canonical badge row; **Dependencies** (Efferent / Afferent); related projects; License → `./LICENSE`; * **EXAMPLES.md** example links are repo-relative (`./examples/…`); * `elide_redundant_path_name_separators!` is freeze-safe (Ruby 3.4 `FrozenError` on a frozen remainder, e.g. malformed UNC); diff --git a/NEWS.md b/NEWS.md index 5b4c068..45878e4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,7 +2,7 @@ | Date | News Item | | ----------------- | -------------------------------------------------------------------------------------------- | -| 19th August 2026 | [**libpath.Ruby** 0.2.4](https://github.com/synesissoftware/libpath.Ruby/releases/tag/0.2.4) | +| 27th August 2026 | [**libpath.Ruby** 0.2.4](https://github.com/synesissoftware/libpath.Ruby/releases/tag/0.2.4) | | 15th August 2026 | [**libpath.Ruby** 0.2.3](https://github.com/synesissoftware/libpath.Ruby/releases/tag/0.2.3) | | 13th April 2024 | [**libpath.Ruby** 0.2.2.3](https://github.com/synesissoftware/libpath.Ruby/releases/tag/0.2.2.3) | | 7th April 2024 | **libpath.Ruby** 0.2.2.2 released | diff --git a/lib/libpath/internal_/unix/form.rb b/lib/libpath/internal_/unix/form.rb index 69d1b0b..18e1006 100644 --- a/lib/libpath/internal_/unix/form.rb +++ b/lib/libpath/internal_/unix/form.rb @@ -73,12 +73,9 @@ def self.elide_redundant_path_name_separators s # :nodoc: # time # # @!visibility private - def self.elide_redundant_path_name_separators! s # :nodoc: - - s = s.dup if s.frozen? - s.gsub!(/\/\/+/, '/') + def self.elide_redundant_path_name_separators s # :nodoc: - s + s.gsub(/\/\/+/, '/') end diff --git a/lib/libpath/internal_/windows/form.rb b/lib/libpath/internal_/windows/form.rb index 9c9fa96..9702472 100644 --- a/lib/libpath/internal_/windows/form.rb +++ b/lib/libpath/internal_/windows/form.rb @@ -79,12 +79,9 @@ def self.elide_redundant_path_name_separators s # :nodoc: # time # # @!visibility private - def self.elide_redundant_path_name_separators! s # :nodoc: - - s = s.dup if s.frozen? - s.gsub!(/[\\\/]{2,}/, '\\') + def self.elide_redundant_path_name_separators s # :nodoc: - s + s.gsub(/[\\\/]{2,}/, '\\') end # [INTERNAL] This function is undocumented, and subject to change at any @@ -209,7 +206,7 @@ def self.split_path s # :nodoc: f1_volume, rem, frm = self.get_windows_volume s - rem = self.elide_redundant_path_name_separators! rem + rem = self.elide_redundant_path_name_separators rem f1_volume.define_singleton_method(:form) { frm } if f1_volume diff --git a/lib/libpath/util/windows.rb b/lib/libpath/util/windows.rb index 2843d66..0a0ba1e 100644 --- a/lib/libpath/util/windows.rb +++ b/lib/libpath/util/windows.rb @@ -492,7 +492,7 @@ def make_path_absolute path, **options vol, rem, _ = _Internal_Windows_Form.get_windows_volume r - rem = _Internal_Windows_Form.elide_redundant_path_name_separators! rem + rem = _Internal_Windows_Form.elide_redundant_path_name_separators rem r = "#{vol}#{rem}" end diff --git a/lib/libpath/version.rb b/lib/libpath/version.rb index 33f1c86..f73a03f 100644 --- a/lib/libpath/version.rb +++ b/lib/libpath/version.rb @@ -5,7 +5,7 @@ # Purpose: Version for libpath.Ruby library # # Created: 8th January 2019 -# Updated: 19th August 2026 +# Updated: 27th August 2026 # # Home: https://github.com/synesissoftware/libpath.Ruby #