diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8d78c5d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,64 @@ +root = true + +# Language indent/EOL/charset overlap with .vscode/settings.json. +# Rulers, renderWhitespace, detectIndentation, mergeEditor, and +# cmake.configureOnOpen cannot be expressed here — they stay in settings.json. + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true + +# [bat] +[*.{bat,cmd}] +end_of_line = crlf +indent_size = 4 +indent_style = space + +# [c] +[*.{c,h}] +indent_size = 4 +indent_style = space + +# [cmake] +[{CMakeLists.txt,*.cmake}] +indent_size = 4 +indent_style = tab + +# [cpp] +[*.{cpp,cxx,hpp,hxx}] +indent_size = 4 +indent_style = space + +# [json] +[*.json] +indent_size = 2 +indent_style = space + +# [markdown] +[*.md] +indent_size = 2 +indent_style = space +trim_trailing_whitespace = false + +# [ruby] +[*.{gemspec,rb}] +indent_size = 2 +indent_style = space + +[{Gemfile,Rakefile}] +indent_size = 2 +indent_style = space + +# [shellscript] +[*.{bash,sh,zsh}] +indent_size = 2 +indent_style = space + +# [yaml] +[*.{yaml,yml}] +indent_size = 2 +indent_style = space diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..2c70232 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,75 @@ +# .gitattributes — Ruby (GitHub-hosted) +# +# Sources: GitHub Docs (line endings), git-scm gitattributes (diff=ruby), +# gitattributes/gitattributes Common.gitattributes + Web (*.rb), +# github-linguist overrides. + +# Default: detect text, normalize to LF in the repository +* text=auto + +# --- Source --- +*.gemspec text eol=lf diff=ruby +*.rake text eol=lf diff=ruby +*.rb text eol=lf diff=ruby +*.ru text eol=lf diff=ruby +Gemfile text eol=lf diff=ruby +Rakefile text eol=lf diff=ruby +Capfile text eol=lf diff=ruby +Guardfile text eol=lf diff=ruby +*.erb text +*.haml text +*.slim text + +# --- Lock / config --- +Gemfile.lock text +*.gemspec.lock text -diff +*.yml text +*.yaml text +*.toml text +*.json text + +# --- Scripts --- +*.bash text eol=lf +*.bat text eol=crlf +*.cmd text eol=crlf +*.ps1 text eol=crlf +*.sh text eol=lf +*.zsh text eol=lf + +# --- Docs / meta --- +*.adoc text +*.markdown text diff=markdown +*.md text diff=markdown +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +LICENSE text +NEWS text +README text +TODO text +.gitattributes text +.gitignore text + +# --- Binary --- +*.gem binary +*.so binary + +# --- Archives / images (common) --- +*.gif binary +*.gz binary +*.ico binary +*.jpeg binary +*.jpg binary +*.png binary +*.tar binary +*.zip binary + +# --- GitHub Linguist --- +**/vendor/bundle/** linguist-vendored +**/vendor/cache/** linguist-vendored +**/coverage/** linguist-generated +**/doc/** linguist-documentation +**/pkg/** linguist-generated diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..3189593 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - directory: / + package-ecosystem: bundler + schedule: + interval: weekly + - directory: / + package-ecosystem: github-actions + schedule: + interval: weekly diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 336c880..5093859 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 @@ -15,10 +15,10 @@ name: Ruby on: push: branches: - - boilerplate + - master - dev + - boilerplate - idiomatic - - master - rc1 - rc2 - rc3 @@ -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 + # 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 @@ -89,7 +96,7 @@ jobs: run: | gem build woad.gemspec gem install --local woad-*.gem - ruby -e "require 'woad'; abort('VERSION missing') unless defined?(Woad::VERSION); puts Woad::VERSION" + ruby -e "require 'woad/version'; abort('VERSION missing') unless defined?(Woad::VERSION); puts Woad::VERSION" warnings: @@ -102,16 +109,20 @@ 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 - - name: Require library with warnings - run: ruby -w -Ilib -e "require 'woad'" + - name: Run unit tests with warnings + run: ./run_all_unit_tests.sh --lib --warnings diff --git a/.gitignore b/.gitignore index 5d0ba7d..ce639ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,13 @@ # directories (by name) -/.bzr/ /.bundle/ +/.bzr/ /.config/ /.svn/ +/.vscode/ /.yardoc/ +/_build/ /_yardoc/ /InstalledFiles/ @@ -34,6 +36,8 @@ .ruby-version .rvmrc +Gemfile.lock + /spec/examples.txt diff --git a/.sis/project_name.txt b/.sis/project_name.txt new file mode 100644 index 0000000..3ea7220 --- /dev/null +++ b/.sis/project_name.txt @@ -0,0 +1 @@ +woad.Ruby diff --git a/AUTHORS.md b/AUTHORS.md index 98f87ff..f3d5bf4 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -10,9 +10,9 @@ ## Defect reports, fixes and suggestions (for which we are very grateful) -| Name | GitHub | -| ------- | ------ | -| \ | | +| Name | GitHub | +| ----------- | --------------------------------- | +| \ | | Contributions are welcomed. diff --git a/CHANGES.md b/CHANGES.md index 50db8dc..7cedbe4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,18 @@ # woad.Ruby - Changes +## 0.0.2 - 19th August 2026 + +* **EXAMPLES.md** catalog and **examples/print_status**; +* reordered **README.md** (canonical sections; **Examples**; **Dependencies** Efferent / Afferent); dropped GitHub-release badge; +* expanded **woad.gemspec** `spec.summary` to the README tagline; packaged **AUTHORS**, **CHANGES**, **CONTRIBUTING**, **EXAMPLES**, **FAQ**, **INSTALL**, **NEWS**, **SECURITY**, and **TODO**; +* **woad.gemspec**: `required_ruby_version` is the range `>= 2.0` (dropped `< 5`); **Gemfile.lock** and **.ruby-version** excluded from `spec.files`; +* **Gemfile** sets `lockfile false` when Bundler supports it; **.gitignore** includes **Gemfile.lock**; CI uses `bundler-cache: false` because Bundler 4 then writes no lockfile and **ruby/setup-ruby** cache cats **Gemfile.lock**; +* CI **Warnings** job now runs on Ruby **3.4** via **run_all_unit_tests.sh** `--lib --warnings`; +* added **run_all_unit_tests.sh** (from https://github.com/synesissoftware/misc-dev-scripts) that skips **tput** when **$TERM** is unset or stdout is not a TTY; +* library source **Home:** URL now uses `https`; + + ## 0.0.1 - 15th August 2026 * SGR colour and reset codes (`RESET`, `FG_*`, `BG_*`, including bright variants); diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..673ea6f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,36 @@ +# woad.Ruby - Contributing + + +## Table of Contents + +- [Defects and features](#defects-and-features) +- [Pull requests](#pull-requests) +- [Tests](#tests) +- [License](#license) + + +## Defects and features + +Open an issue on https://github.com/synesissoftware/woad.Ruby/issues. + + +## Pull requests + +Pull requests are welcome on https://github.com/synesissoftware/woad.Ruby. Keep diffs local to the change; match existing indentation (2 spaces in Ruby) and the Synesis markdown set (**README.md**, **CHANGES.md**, **NEWS.md**, **TODO.md**, **INSTALL.md**, **CONTRIBUTING.md**, **SECURITY.md**). + + +## Tests + +``` +bundle exec rake test +``` + +or `./run_all_unit_tests.sh`. + + +## License + +Contributions are accepted under the 3-clause BSD license. See [LICENSE](./LICENSE). + + + diff --git a/EXAMPLES.md b/EXAMPLES.md new file mode 100644 index 0000000..d61c073 --- /dev/null +++ b/EXAMPLES.md @@ -0,0 +1,8 @@ +# woad.Ruby - Examples + +|Name|Source & Description|Summary| +|---|---|---| +|**print_status**|[examples/print_status.rb](./examples/print_status.rb)
[examples/print_status.md](./examples/print_status.md)|Prints sample status words with **woad** SGR colour constants| + + + diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000..e324b7e --- /dev/null +++ b/FAQ.md @@ -0,0 +1,28 @@ +# woad.Ruby - FAQ + +The FAQ list is under (constant) development. If you post a question on the +[Issues](https://github.com/synesissoftware/woad.Ruby/issues) forum +it will be used to create one. + + +## Table of Contents + +- [Q1: "How do I install this library?"](#q1-how-do-i-install-this-library) + + +# FAQs: + + +## Q1: "How do I install this library?" + +Install via **gem**: + +``` +gem install woad +``` + +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/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..2852e60 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,43 @@ +# woad.Ruby - Installation and Use + + +## Table of Contents + +- [Install the gem](#install-the-gem) +- [From a source checkout](#from-a-source-checkout) +- [Using the library](#using-the-library) + + +## Install the gem + +``` +gem install woad +``` + +or add to a **Gemfile**: + +```Ruby +gem 'woad' +``` + +then `bundle install`. + + +## From a source checkout + +``` +bundle install +bundle exec rake test +``` + + +## Using the library + +```Ruby +require 'woad' + +puts "#{Woad::FG_GREEN}ok#{Woad::RESET}" +``` + + + diff --git a/NEWS.md b/NEWS.md index 1fdab37..93e5c7c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ | Date | News Item | | ---------------- | -------------------------------------------------------------------------------------- | +| 20th August 2026 | [**woad.Ruby** 0.0.2](https://github.com/synesissoftware/woad.Ruby/releases/tag/0.0.2) | | 15th August 2026 | [**woad.Ruby** 0.0.1](https://github.com/synesissoftware/woad.Ruby/releases/tag/0.0.1) | | 15th August 2026 | [**woad.Ruby** 0.0.0](https://github.com/synesissoftware/woad.Ruby/releases/tag/0.0.0) | diff --git a/README.md b/README.md index 1225abc..77e5c2a 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ Minimal ANSI terminal colour codes, 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/woad.svg)](https://badge.fury.io/rb/woad) -[![GitHub release](https://img.shields.io/github/v/release/synesissoftware/woad.Ruby.svg)](https://github.com/synesissoftware/woad.Ruby/releases/latest) [![Last Commit](https://img.shields.io/github/last-commit/synesissoftware/woad.Ruby)](https://github.com/synesissoftware/woad.Ruby/commits/master) [![Ruby](https://github.com/synesissoftware/woad.Ruby/actions/workflows/ruby.yml/badge.svg)](https://github.com/synesissoftware/woad.Ruby/actions/workflows/ruby.yml) @@ -15,11 +14,17 @@ Minimal ANSI terminal colour codes, for Ruby - [Introduction](#introduction) - [Installation](#installation) - [Components](#components) +- [Examples](#examples) - [Project Information](#project-information) - [Where to get help](#where-to-get-help) - [Contribution guidelines](#contribution-guidelines) - [Dependencies](#dependencies) - - [Development Dependencies](#development-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) @@ -28,7 +33,9 @@ Minimal ANSI terminal colour codes, for Ruby **woad** provides the smallest useful set of fixed ANSI SGR colour sequences for library authors. It is not a console or TUI framework. -**woad.Ruby** is the **Ruby** implementation. It supports **Ruby 2.0** through **3.x**. +**woad.Ruby** is the **Ruby** implementation. It supports **Ruby 2.0+**. + +It has **no dependencies** on any other non-standard library. ## Installation @@ -55,6 +62,11 @@ puts "#{Woad::FG_GREEN}ok#{Woad::RESET}" **woad.Ruby** ships SGR string constants (`RESET`, `FG_*`, `BG_*`, including bright variants). TTY/stream gating and Windows virtual-terminal opt-in are not implemented yet. +## Examples + +Examples are provided in the ```examples``` directory, along with a markdown description for each. A detailed list TOC of them is provided in [EXAMPLES.md](./EXAMPLES.md). + + ## Project Information @@ -70,20 +82,43 @@ Defect reports, feature requests, and pull requests are welcome on https://githu ### Dependencies -* \ + +#### Efferent (fan-out) + +Libraries upon which **woad.Ruby** depends: + + +##### Runtime Dependencies (aka "Normal Dependencies") + +* \; + + +##### Development Dependencies + +* [**rake**](https://rubygems.org/gems/rake); +* [**test-unit**](https://rubygems.org/gems/test-unit); + + +#### Afferent (fan-in) + +Projects that depend on **woad.Ruby**: + + +##### Runtime dependents + +* \; -#### Development Dependencies +##### Development dependents -* [**rake**](https://github.com/ruby/rake) -* [**test-unit**](https://github.com/test-unit/test-unit) +* \; ### Related projects -* [**woad**](https://github.com/synesissoftware/woad/) -* [**woad.Python**](https://github.com/synesissoftware/woad.Python/) -* [**woad.Rust**](https://github.com/synesissoftware/woad.Rust/) +* [**woad**](https://github.com/synesissoftware/woad/) (**C**); +* [**woad.Python**](https://github.com/synesissoftware/woad.Python/); +* [**woad.Rust**](https://github.com/synesissoftware/woad.Rust/); ### License diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..2bdf634 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,22 @@ +# woad.Ruby - Security + + +## Table of Contents + +- [Reporting a vulnerability](#reporting-a-vulnerability) +- [Supported versions](#supported-versions) + + +## Reporting a vulnerability + +Please report security issues privately via GitHub Security Advisories on https://github.com/synesissoftware/woad.Ruby/security, or by opening an issue if an advisory cannot be filed. Do not attach exploit proofs of concept against third-party systems. + + +## Supported versions + +| Version | Supported | +| ------- | --------- | +| 0.0.x | ✅ | + + + diff --git a/TODO.md b/TODO.md index 684f018..2539ea1 100644 --- a/TODO.md +++ b/TODO.md @@ -15,7 +15,11 @@ ## Packaging improvements -* \ +* [x] ~~~added **run_all_unit_tests.sh** (from **misc-dev-scripts**) that skips `tput` when `$TERM` is unset or stdout is not a TTY~~~; +* [x] ~~~**Gemfile** `lockfile false`; gitignore **Gemfile.lock**; CI `bundler-cache: false`~~~; +* [x] ~~~gemspec polish: README tagline as `spec.summary`, drop `< 5` upper bound, package docs, exclude **Gemfile.lock** / **.ruby-version**~~~; +* [x] ~~~README canonical structure (tagline before badges; **Dependencies**; CI badge → **ruby.yml**); added **examples/print_status**~~~; +* [x] ~~~after the packaging/boilerplate/CI baseline: bump **VERSION** and align **CHANGES**/**NEWS**~~~; diff --git a/build_gem.cmd b/build_gem.cmd new file mode 100644 index 0000000..c894c21 --- /dev/null +++ b/build_gem.cmd @@ -0,0 +1,13 @@ +@ECHO OFF + +REM ######################################################################## +REM File: build_gem.cmd +REM +REM Purpose: Builds the gem +REM +REM Created: 11th July 2016 +REM Updated: 14th August 2026 +REM +REM ######################################################################## + +FOR %%f IN (*.gemspec) DO gem build "%%f" %* diff --git a/examples/print_status.md b/examples/print_status.md new file mode 100644 index 0000000..e7d13bd --- /dev/null +++ b/examples/print_status.md @@ -0,0 +1,35 @@ +# woad.Ruby - Example - **print_status** + +## Summary + +Prints sample status words using **woad** SGR foreground constants and **RESET**. + +## Source + +```ruby + +#! /usr/bin/env ruby + +# examples/print_status.rb + +require 'woad' + +puts "#{Woad::FG_GREEN}ok#{Woad::RESET}" +puts "#{Woad::FG_YELLOW}warn#{Woad::RESET}" +puts "#{Woad::FG_RED}error#{Woad::RESET}" +``` + +On a colour-capable terminal the words appear in green, yellow, and red, then the SGR state is reset. + +## Usage + +When run, this produces the following output (colours omitted here): + +``` +ok +warn +error +``` + + + diff --git a/examples/print_status.rb b/examples/print_status.rb new file mode 100644 index 0000000..89891ba --- /dev/null +++ b/examples/print_status.rb @@ -0,0 +1,11 @@ +#! /usr/bin/env ruby + +# examples/print_status.rb + + +require 'woad' + + +puts "#{Woad::FG_GREEN}ok#{Woad::RESET}" +puts "#{Woad::FG_YELLOW}warn#{Woad::RESET}" +puts "#{Woad::FG_RED}error#{Woad::RESET}" diff --git a/generate_rdoc.cmd b/generate_rdoc.cmd new file mode 100644 index 0000000..4f6f7ad --- /dev/null +++ b/generate_rdoc.cmd @@ -0,0 +1,28 @@ +@ECHO OFF + +REM ######################################################################## +REM File: generate_rdoc.cmd +REM +REM Purpose: Generates documentation +REM +REM Created: 14th August 2026 +REM Updated: 14th August 2026 +REM +REM ######################################################################## + +IF EXIST doc RMDIR /S /Q doc +rdoc ^ + -x build_gem.cmd ^ + -x build_gem.sh ^ + -x generate_rdoc.cmd ^ + -x generate_rdoc.sh ^ + -x run_all_unit_tests.sh ^ + -x *.gemspec ^ + -x doc/ ^ + -x gems/ ^ + -x old-gems/ ^ + -x test/performance/ ^ + -x test/scratch/ ^ + -x tc_.*\.rb ^ + -x ts_all.rb ^ + %* diff --git a/generate_rdoc.sh b/generate_rdoc.sh new file mode 100755 index 0000000..e7dc865 --- /dev/null +++ b/generate_rdoc.sh @@ -0,0 +1,31 @@ +#! /bin/bash + +############################################################################# +# File: generate_rdoc.sh +# +# Purpose: Generates documentation +# +# Created: 11th June 2016 +# Updated: 14th August 2026 +# +############################################################################# + +rm -rfd doc +rdoc \ + -x build_gem.cmd \ + -x build_gem.sh \ + -x generate_rdoc.cmd \ + -x generate_rdoc.sh \ + -x run_all_unit_tests.sh \ + -x *.gemspec \ + \ + -x doc/ \ + -x gems/ \ + -x old-gems/ \ + -x test/performance/ \ + -x test/scratch/ \ + \ + -x tc_.*\.rb \ + -x ts_all.rb \ + \ + $* diff --git a/lib/woad.rb b/lib/woad.rb index a8a45c6..57ebba8 100644 --- a/lib/woad.rb +++ b/lib/woad.rb @@ -5,9 +5,9 @@ # Purpose: Primary require for woad.Ruby library # # Created: 15th August 2026 -# Updated: 15th August 2026 +# Updated: 19th August 2026 # -# Home: http://github.com/synesissoftware/woad.Ruby +# Home: https://github.com/synesissoftware/woad.Ruby # # Author: Matthew Wilson # diff --git a/lib/woad/version.rb b/lib/woad/version.rb index 7e56c82..ded256d 100644 --- a/lib/woad/version.rb +++ b/lib/woad/version.rb @@ -5,9 +5,9 @@ # Purpose: Version for woad.Ruby library # # Created: 15th August 2026 -# Updated: 15th August 2026 +# Updated: 20th August 2026 # -# Home: http://github.com/synesissoftware/woad.Ruby +# Home: https://github.com/synesissoftware/woad.Ruby # # Author: Matthew Wilson # @@ -50,7 +50,7 @@ module Woad # Current version of the woad.Ruby library - VERSION = '0.0.1' + VERSION = '0.0.2' private # @!visibility private diff --git a/run_all_unit_tests.sh b/run_all_unit_tests.sh new file mode 100755 index 0000000..0a05634 --- /dev/null +++ b/run_all_unit_tests.sh @@ -0,0 +1,313 @@ +#! /bin/bash + +# ######################################################################## # +# File: run_all_unit_tests.sh +# +# Purpose: Executes the unit-tests of a Ruby project regardless of +# calling directory, allowing use of debug mode, warnings, and +# executing each rbenv version +# +# Created: 9th June 2011 +# Updated: 19th August 2026 +# +# Copyright (c) Matthew Wilson, 2011-2026 +# All rights reserved +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# ######################################################################## # + + +# constants + +Source="${BASH_SOURCE[0]}" +while [ -h "$Source" ]; do + + ScriptDir="$(cd -P "$(dirname "$Source")" && pwd)" + Source="$(readlink "$Source")" + [[ $Source != /* ]] && Source="$ScriptDir/$Source" +done +ScriptDir="$(cd -P "$( dirname "$Source" )" && pwd)" +Basename="$(basename "$Source")" + + +# colours + +SisClr_Blue=${FG_BLUE:-} +SisClr_Red=${FG_RED:-} +SisClr_Bold=${FD_BOLD:-} +SisClr_None=${FD_NONE:-} + +if [ -n "${TERM:-}" ] && [ -t 1 ] && command -v tput >/dev/null 2>&1; then + + if tput sgr0 >/dev/null 2>&1; then + + 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 + + +# special command-line handling ('--pwd', '--rbenv-versions') + +ProjectDir="$ScriptDir" +ForwardArgs=() +FoundHelp= +RunRbEnvAllVersions= + +for arg in "$@" +do + + case "$arg" in + + --help) + + FoundHelp=1 + ForwardArgs+=("$arg") + ;; + --pwd) + + ProjectDir=$(pwd) + ForwardArgs+=("$arg") + ;; + --rbenv-versions) + + RunRbEnvAllVersions=1 + ;; + *) + + ForwardArgs+=("$arg") + ;; + esac +done + +if [ ! -z "$FoundHelp" ]; then + + RunRbEnvAllVersions= +fi + +if [ ! -z "$RunRbEnvAllVersions" ]; then + + if ! command -v rbenv > /dev/null; then + + >&2 echo "$0: ${SisClr_Red}${SisClr_Bold}rbenv${SisClr_None} not detected" + + exit 1 + fi + + exclusions=() + if [ -e "$ProjectDir/.ruby-version-exclusions" ]; then + + exclusion_lines=`cat "$ProjectDir/.ruby-version-exclusions"` + for line in $exclusion_lines; do + + exclusions+=("$line") + done + fi + + echo "executing command line '${SisClr_Blue}${SisClr_Bold}$0 ${ForwardArgs[*]}${SisClr_None}' with all Ruby versions ..." + + current= + if [ -f "$ProjectDir/.ruby-version" ]; 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=() + if [ -n "$version_output" ]; then + + 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}" + + result=0 + + for version in "${versions[@]}" + do + + echo + + skip= + + for exclusion in "${exclusions[@]}"; do + + if [[ "$exclusion" == "$version" ]]; then + + skip=1 + fi + done + + if [ "$skip" != "" ]; then + + echo "skipping Ruby version ${SisClr_Blue}${SisClr_Bold}$version${SisClr_None}:" + else + + 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 ..." + + if ! RBENV_VERSION="$version" "$0" "${ForwardArgs[@]}"; then + + result=1 + fi + fi + done + + exit $result +fi + + +# regular command-line handling + +Separate= +DebugFlag= +PrependLib= +WarningsFlag=-W0 + +for v in "$@" +do + + case "$v" in + + --debug) + + DebugFlag=--debug + ;; + --help) + + cat << EOF +USAGE: $Basename { | --help | [ --debug ] [ --lib ] [ --pwd ] [ --rbenv-versions ] [ --separate ] [ --warnings ]} + +flags: + + --help + shows this help and terminates + + --debug + executes Ruby interpreter in debug mode + + --lib + prepends the lib directory under the script's directory into RUBYLIB before executing + + --pwd + executes from present working directory, rather than relative to the script directory + + --rbenv-versions + executes this script (with all other specified arguments) for each rbenv version (except those listed in the file .ruby-version-exclusions, if present) + + --separate + executes each unit-test in a separate program + + --warnings + executes Ruby interpreter in warnings mode +EOF + + exit 0 + ;; + --lib) + + PrependLib=1 + ;; + --pwd) + + # already-processed as special case above + ;; + --rbenv-versions) + + # already-processed as special case above + ;; + --separate) + + Separate=true + ;; + --warnings|--warn) + + WarningsFlag=-W2 #-W:performance + ;; + *) + + >&2 echo "unrecognised argument '$v'; use --help for usage" + + exit 1 + ;; + esac +done + + +# executing tests + +if [ ! -z "$PrependLib" ]; then + + export RUBYLIB=$ProjectDir/lib:$RUBYLIB +fi + + +if [ -z "$Separate" ]; then + + ruby $DebugFlag $WarningsFlag "$ProjectDir/test/unit/ts_all.rb" +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 < "$test_files" + + exit $result +fi + + +# ############################## end of file ############################# # + diff --git a/test/unit/ts_all.rb b/test/unit/ts_all.rb new file mode 100644 index 0000000..5a271c5 --- /dev/null +++ b/test/unit/ts_all.rb @@ -0,0 +1,12 @@ +#! /usr/bin/env ruby +# +# executes all other tests + +this_dir = File.expand_path(File.dirname(__FILE__)) + +# all tc_*rb in current directory +Dir[File.join(this_dir, 'tc_*rb')].each { |file| require file } + +# all ts_*rb in immediate sub-directories +Dir[File.join(this_dir, '*', 'ts_*rb')].each { |file| require file } + diff --git a/woad.gemspec b/woad.gemspec index 30d0f6a..b65ee2d 100644 --- a/woad.gemspec +++ b/woad.gemspec @@ -1,12 +1,12 @@ -# ######################################################################### # +# ######################################################################## # # File: woad.gemspec # # Purpose: Gemspec for woad.Ruby library # # Created: 15th August 2026 -# Updated: 15th August 2026 +# Updated: 19th August 2026 # -# ######################################################################### # +# ######################################################################## # $:.unshift File.join(File.dirname(__FILE__), 'lib') @@ -17,8 +17,8 @@ require 'woad/version' Gem::Specification.new do |spec| spec.name = 'woad' + spec.summary = 'Minimal ANSI terminal colour codes, for Ruby' spec.version = Woad::VERSION - spec.summary = 'woad.Ruby' spec.description = <= 2.0', '< 5' ] - - spec.require_paths = [ - 'lib', - ] + spec.required_ruby_version = [ '>= 2.0' ] spec.metadata = { 'bug_tracker_uri' => 'https://github.com/synesissoftware/woad.Ruby/issues', @@ -47,7 +43,25 @@ END_DESC 'source_code_uri' => 'https://github.com/synesissoftware/woad.Ruby', } - spec.files = Dir[ 'Rakefile', '{bin,examples,lib,man,spec,test}/**/*', 'AUTHORS.md', 'CHANGES.md', 'LICENSE*', 'NEWS.md', 'README*', 'TODO.md' ] + 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', + ] end