README.md in runcom-3.1.0 vs README.md in runcom-4.0.0
- old
+ new
@@ -5,27 +5,32 @@
[![Code Climate Test Coverage](https://api.codeclimate.com/v1/badges/129b7ea524a0f5a6a805/test_coverage)](https://codeclimate.com/github/bkuhlmann/runcom/test_coverage)
[![Circle CI Status](https://circleci.com/gh/bkuhlmann/runcom.svg?style=svg)](https://circleci.com/gh/bkuhlmann/runcom)
Runcom (a.k.a. [Run Command](https://en.wikipedia.org/wiki/Run_commands)) provides common
functionality for Command Line Interfaces (CLIs) in which to manage global, local, or multiple
-configurations in general. It does this by leveraging the
-[XDG Base Directory Specification](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html).
-Read on for further details.
+caches, configurations, or data in general. It does this by leveraging the [XDG Base Directory
+Specification](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html). Read on for
+further details.
<!-- Tocer[start]: Auto-generated, don't remove. -->
## Table of Contents
- [Features](#features)
- [Requirements](#requirements)
- [Setup](#setup)
- [Usage](#usage)
- - [`Runcom::Configuration`](#runcomconfiguration)
- [XDG](#xdg)
- - [`$XDG_CONFIG_DIRS`](#xdg_config_dirs)
- - [`$XDG_CONFIG_HOME`](#xdg_config_home)
+ - [Overview](#overview)
+ - [Variable Behavior](#variable-behavior)
+ - [`$XDG_*_DIRS`](#xdg__dirs)
+ - [`$XDG_*_HOME`](#xdg__home)
- [Variable Priority](#variable-priority)
+ - [Runcom](#runcom)
+ - [Overview](#overview-1)
+ - [Variable Priority](#variable-priority-1)
+ - [Configuration Specialization](#configuration-specialization)
- [Examples](#examples)
- [Tests](#tests)
- [Versioning](#versioning)
- [Code of Conduct](#code-of-conduct)
- [Contributions](#contributions)
@@ -35,23 +40,26 @@
<!-- Tocer[finish]: Auto-generated, don't remove. -->
## Features
-- Provides run command customization by loading a CLI-specific configuration from a
- [YAML](http://yaml.org) file.
-- Automatically detects and resolves resource configuration file path based on XDG environment
- variables which provides several benefits:
- - Uses the `$XDG_CONFIG_HOME` or `$XDG_CONFIG_DIRS` variables to define configuration paths.
- - Improves configuration organization by not littering your `$HOME` directory with `*rc` files and
- keeping them within a central configuration folder.
-- Supports loading and merging of nested/complex configurations.
-- Supports hash representation of configuration.
+- Provides an embedded `XDG::Environment` implementation that strictly adheres to the *XDG Base
+ Directory Specification* which provides access to the following environment settings:
+ - `$XDG_CACHE_HOME`
+ - `$XDG_CONFIG_HOME`
+ - `$XDG_CONFIG_DIRS`
+ - `$XDG_DATA_HOME`
+ - `$XDG_DATA_DIRS`
+- Provides a developer friendly wrapping of the XDG implementation for cache, config, and data. For
+ the config, the following is supported:
+ - Supports loading of CLI-specific [YAML](http://yaml.org) configuration file.
+ - Supports loading and merging of nested/complex configurations.
+ - Supports hash representation of configuration.
## Requirements
-0. [Ruby 2.5.x](https://www.ruby-lang.org)
+1. [Ruby 2.6.x](https://www.ruby-lang.org).
## Setup
Type the following to install:
@@ -61,56 +69,52 @@
gem "runcom"
## Usage
-### `Runcom::Configuration`
+This gem provides an embedded XDG implementation along with a developer friendly wrapper
+implementation. Both of which are described in detail below.
-This object provides support for loading custom CLI configurations directly from the command line or
-from custom locations. It is meant to be used within your CLI program(s).
+### XDG
-An object can be initialized as follows:
+The following describes the embedded XDG implementation. It's worth noting there is a [XDG
+Gem](https://github.com/rubyworks/xdg) which also implements the *XDG Base Directory Specification*
+but hasn't been updated in ~6 years.
- configuration = Runcom::Configuration.new "example"
+#### Overview
-The default file name for a configuration is `configuration.yml` but a custom name can be used if
-desired:
+Provides an API that strictly adheres to the *XDG Base Directory Specification*. Usage:
- configuration = Runcom::Configuration.new "example", file_name: "example.yml"
+ xdg = Runcom::XDG::Environment.new
+ xdg.cache_home # <= Answers computed `$XDG_CACHE_HOME` value.
+ xdg.config_home # <= Answers computed `$XDG_CONFIG_HOME` value.
+ xdg.config_dirs # <= Answers computed `$XDG_CONFIG_DIRS` value.
+ xdg.data_home # <= Answers computed `$XDG_DATA_HOME` value.
+ xdg.data_dirs # <= Answers computed `$XDG_DATA_DIRS` value.
-Default settings can be initialized as well:
+`Runcom::XDG::Environment` wraps the following objects which can be used individually if you don't
+want to load the entire environment:
- configuration = Runcom::Configuration.new "example", defaults: {name: "Example"}
+ cache = Runcom::XDG::Cache.new
+ config = Runcom::XDG::Config.new
+ data = Runcom::XDG::Data.new
-Once a configuration has been initialized, a hash representation can be obtained:
+The `cache`, `config`, and `data` objects share the same API which means you can ask each the
+following messages:
- configuration.to_h
+- `#home` - Answers the home directory as computed via the `$XDG_*_HOME` key.
+- `#directories` - Answers an array directories as computed via the `$XDG_*_DIRS` key.
+- `#all` - Answers an array of *all* directories as computed from the combined `$XDG_*_HOME` and
+ `$XDG_*_DIRS` values (with `$XDG_*_HOME` prefixed at the start of the array).
-A configuration can be merged with another hash (handy for runtime overrides):
+#### Variable Behavior
- updated_configuration = configuration.merge {name: "Updated Name"}
+The behavior of all XDG environment variables can be lumped into two categories of `$XDG_*_HOME` and
+`$XDG_*_DIRS` behavior. Each is described below.
-A configuration can also be merged with another configuration:
+##### `$XDG_*_DIRS`
- updated_configuration = configuration.merge Runcom::Configuration.new("other", defaults: {a: 1})
-
-The computed path of the configuration can be asked for as well:
-
- configuration.path # "~/.config/example/configuration.yml"
-
-For further details, study the public interface as provided by the
-[`Runcom::Configuration`](lib/runcom/configuration.rb) object.
-
-### XDG
-
-This gem leverages the XDG `$XDG_CONFIG_DIRS` and `$XDG_CONFIG_HOME` environment variables which are
-used to compute the configuration path (as mentioned above). The following details how to take
-advantage of the XDG variables (additional details can be found by reading the
-[XDG Specification](https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html)).
-
-#### `$XDG_CONFIG_DIRS`
-
This variable is used to define a colon delimited list of configuration directories. The order is
important as the first directory defined will take precedent over the following directory and so
forth. Example:
XDG_CONFIG_DIRS="/example/one/.config:/example/two/.settings:/example/three/.configuration"
@@ -124,79 +128,125 @@
In the above example, the `"/example/one/.config"` path will take highest priority since it was
defined first.
When the `$XDG_CONFIG_DIRS` is not defined, it will default to the following array: `["/etc/xdg"]`.
+Other `$XDG_*_DIRS` variables share similar behavior.
-#### `$XDG_CONFIG_HOME`
+##### `$XDG_*_HOME`
This is the environment variable you'll want to use the most as it takes precidence over
-`$XDG_CONFIG_DIRS` environment variable. It is not required to be defined as it defaults to
-`$HOME/.config` which is generally want you want.
+`$XDG_*_DIRS` environment variable. When not defined, it defaults to `$HOME/.config` which is
+generally want you want. Other `$XDG_*_HOME` variables share similar behavior.
#### Variable Priority
Configuration path precedence is determined in the following order (with the first taking highest
priority):
-0. `$XDG_CONFIG_HOME` - Will be used if defined *and* exists on the local file system. Otherwise,
- falls back to the `$XDG_CONFIG_DIRS` array.
-0. `$XDG_CONFIG_DIRS` - Iterates through defined directories starting with the first one defined
- (highest priority). It will choose the first directory, in priority, that exists on the file
- system while skipping any that don't exist.
+1. `$XDG_*_HOME` - Will be used if defined. Otherwise, falls back to specification default.
+1. `$XDG_*_DIRS` - Iterates through directories in order defined (with first taking highest
+ priority). Otherwise, falls back to specification default.
-### Examples
+### Runcom
-One of the best use cases of this gem is when it is combined with an environment switcher like
-[direnv](https://direnv.net) where you can define a custom `XDG_CONFIG_HOME` for your specific
-project.
+Provides wrapper objects around the `XDG` objects which extends and enhances beyond what is found in
+the *XDG Base Directory Specification*. This includes preference of local over global
+configurations by default as well as other conveniences.
-With `direnv` installed, you could have the following project structure:
+#### Overview
- /example
- /.config/test/configuration.yml
- /.envrc
+While there isn't an environment convenience object as found in the `XDG` namespace, you can
+instantiate each object individually:
-The `.envrc` file could then have this setting:
+ cache = Runcom::Cache.new
+ config = Runcom::Config.new
+ data = Runcom::Data.new
- export XDG_CONFIG_HOME=".config"
+Each of the above objects share the same basic API:
-This would end up pointing to the `/example/.config` folder of the current project, as shown above,
-instead of `~/.config` (which is the default behavior). While running code within this project, you
-could initialize your configuration object like this:
+- `#path` - Answers first existing file system path first computed by the `$XDG_*_HOME` value
+ followed by each computed `$XDG_*_DIRS` value in the order defined.
+- `#paths` - Answers all file system paths which is the combined `$XDG_*_HOME` and `$XDG_*_DIRS`
+ values in the order defined.
- configuration = Runcom::Configuration.new "test"
+#### Variable Priority
-The `configuration` object would have the following path due `direnv` setting your `XDG_CONFIG_HOME`
-to your current project:
+Configuration path precedence is determined in the following order (with the first taking highest
+priority):
- configuration.path # "~/.config/test/configuration.yml"
+1. **Local Configuration** - If a `$XDG_*_HOME` or `$XDG_*_DIRS` path relative to the current
+ working directory is detected, it will take preference over the global configuration. This is the
+ same behavior as found in Git where the local `.git/config` takes precedence over the global
+ `~/.gitconfig`.
+1. **Global Configuration** - When a local configuration isn't found, the global configuration is
+ used as defined by the *XDG Base Directory Specification*.
+#### Configuration Specialization
+
+The `Runcom::Config` deserves additional highlighting as it provides support for loading custom CLI
+configurations directly from the command line or from custom locations. It is meant to be used
+within your CLI program(s).
+
+An object can be initialized as follows:
+
+ configuration = Runcom::Config.new "example"
+
+The default file name for a configuration is `configuration.yml` but a custom name can be used if
+desired:
+
+ configuration = Runcom::Config.new "example", file_name: "example.yml"
+
+Default settings can be initialized as well:
+
+ configuration = Runcom::Config.new "example", defaults: {name: "Example"}
+
+Once a configuration has been initialized, a hash representation can be obtained:
+
+ configuration.to_h
+
+A configuration can be merged with another hash (handy for runtime overrides):
+
+ updated_configuration = configuration.merge {name: "Updated Name"}
+
+A configuration can also be merged with another configuration:
+
+ updated_configuration = configuration.merge Runcom::Config.new("other", defaults: {a: 1})
+
+The computed path of the configuration can be asked for as well:
+
+ configuration.path # "~/.config/example/configuration.yml"
+
+For further details, study the public interface as provided by the
+[`Runcom::Config`](lib/runcom/config.rb) object.
+
+### Examples
+
If you need further examples of gems that use this gem, check out the following:
- [Gemsmith](https://github.com/bkuhlmann/gemsmith) - A command line interface for smithing new Ruby
gems.
+- [Git Cop](https://github.com/bkuhlmann/git-cop) - Enforces consistent Git commits.
- [Milestoner](https://github.com/bkuhlmann/milestoner) - A command line interface for releasing Git
repository milestones.
-- [Git Cop](https://github.com/bkuhlmann/git-cop) - Enforces consistent Git commits.
-- [Tocer](https://github.com/bkuhlmann/tocer) - A command line interface for generating table of
- contents for Markdown files.
+- [Pennyworth](https://github.com/bkuhlmann/pennyworth) - A command line interface that enhances and
+ extends [Alfred](https://www.alfredapp.com) with Ruby support.
- [Pragmater](https://github.com/bkuhlmann/pragmater) - A command line interface for
managing/formatting source file pragma comments.
- [Sublime Text Kit](https://github.com/bkuhlmann/sublime_text_kit) - A command line interface for
managing Sublime Text metadata.
-- [Pennyworth](https://github.com/bkuhlmann/pennyworth) - A command line interface that enhances and
- extends Alfred with Ruby support.
+- [Tocer](https://github.com/bkuhlmann/tocer) - A command line interface for generating table of
+ contents for Markdown files.
## Tests
To test, run:
bundle exec rake
## Versioning
-Read [Semantic Versioning](http://semver.org) for details. Briefly, it means:
+Read [Semantic Versioning](https://semver.org) for details. Briefly, it means:
- Major (X.y.z) - Incremented for any backwards incompatible public API changes.
- Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes.
- Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes.