myway_config 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'anyway_config'
4
+ require 'yaml'
5
+
6
+ module MywayConfig
7
+ module Loaders
8
+ # XDG Base Directory Specification loader for Anyway Config
9
+ #
10
+ # Loads configuration from XDG-compliant paths:
11
+ # 1. $XDG_CONFIG_HOME/{app}/{app}.yml (if XDG_CONFIG_HOME is set)
12
+ # 2. ~/.config/{app}/{app}.yml (XDG default fallback)
13
+ #
14
+ # On macOS, also checks:
15
+ # 3. ~/Library/Application Support/{app}/{app}.yml
16
+ #
17
+ # This loader runs BEFORE the project-local config loader,
18
+ # so project configs take precedence over user-global configs.
19
+ #
20
+ # @example XDG config file location
21
+ # ~/.config/myapp/myapp.yml
22
+ #
23
+ # @example Custom XDG_CONFIG_HOME
24
+ # export XDG_CONFIG_HOME=/my/config
25
+ # # Looks for /my/config/myapp/myapp.yml
26
+ #
27
+ class XdgConfigLoader < Anyway::Loaders::Base
28
+ class << self
29
+ # Returns all XDG config paths to check for a given app name
30
+ #
31
+ # @param name [String] the application name
32
+ # @return [Array<String>] list of potential config directory paths
33
+ def config_paths(name)
34
+ paths = []
35
+
36
+ # macOS Application Support (lowest priority for XDG loader)
37
+ if macos?
38
+ macos_path = File.expand_path("~/Library/Application Support/#{name}")
39
+ paths << macos_path if Dir.exist?(File.dirname(macos_path))
40
+ end
41
+
42
+ # XDG default: ~/.config/{name}
43
+ xdg_default = File.expand_path("~/.config/#{name}")
44
+ paths << xdg_default
45
+
46
+ # XDG_CONFIG_HOME override (highest priority for XDG loader)
47
+ if ENV['XDG_CONFIG_HOME'] && !ENV['XDG_CONFIG_HOME'].empty?
48
+ xdg_home = File.join(ENV['XDG_CONFIG_HOME'], name.to_s)
49
+ paths << xdg_home unless xdg_home == xdg_default
50
+ end
51
+
52
+ paths
53
+ end
54
+
55
+ # Find the first existing config file for the given app name
56
+ #
57
+ # @param name [String] config name (e.g., 'myapp')
58
+ # @return [String, nil] path to config file or nil if not found
59
+ def find_config_file(name)
60
+ config_paths(name).reverse_each do |dir|
61
+ file = File.join(dir, "#{name}.yml")
62
+ return file if File.exist?(file)
63
+ end
64
+ nil
65
+ end
66
+
67
+ private
68
+
69
+ def macos?
70
+ RUBY_PLATFORM.include?('darwin')
71
+ end
72
+ end
73
+
74
+ def call(name:, **_options)
75
+ config_file = self.class.find_config_file(name)
76
+ return {} unless config_file
77
+
78
+ trace!(:xdg, path: config_file) do
79
+ load_yaml(config_file, name)
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def load_yaml(path, name)
86
+ return {} unless File.exist?(path)
87
+
88
+ content = File.read(path)
89
+ parsed = YAML.safe_load(
90
+ content,
91
+ permitted_classes: [Symbol],
92
+ symbolize_names: true,
93
+ aliases: true
94
+ ) || {}
95
+
96
+ env = current_environment
97
+
98
+ # Check for environment key first, fall back to root level
99
+ if parsed.key?(env.to_sym)
100
+ parsed[env.to_sym] || {}
101
+ elsif parsed.key?(env.to_s)
102
+ parsed[env.to_s] || {}
103
+ else
104
+ # No environment key, treat as flat config
105
+ parsed
106
+ end
107
+ rescue Psych::SyntaxError => e
108
+ warn "MywayConfig: Failed to parse XDG config #{path}: #{e.message}"
109
+ {}
110
+ end
111
+
112
+ def current_environment
113
+ Anyway::Settings.current_environment ||
114
+ ENV['RAILS_ENV'] ||
115
+ ENV['RACK_ENV'] ||
116
+ 'development'
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MywayConfig
4
+ VERSION = "0.1.1"
5
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'anyway_config'
4
+
5
+ require_relative 'myway_config/version'
6
+ require_relative 'myway_config/config_section'
7
+ require_relative 'myway_config/loaders/defaults_loader'
8
+ require_relative 'myway_config/loaders/xdg_config_loader'
9
+ require_relative 'myway_config/base'
10
+
11
+ module MywayConfig
12
+ class Error < StandardError; end
13
+ class ConfigurationError < Error; end
14
+ class ValidationError < Error; end
15
+
16
+ class << self
17
+ # Register the XDG and defaults loaders with Anyway Config
18
+ #
19
+ # Call this method after requiring myway_config to enable
20
+ # XDG config file loading and bundled defaults.
21
+ #
22
+ # The loader order determines priority (lowest to highest):
23
+ # 1. Bundled defaults (DefaultsLoader)
24
+ # 2. XDG user config (XdgConfigLoader)
25
+ # 3. Project config (:yml loader - Anyway default)
26
+ # 4. Environment variables (:env loader - Anyway default)
27
+ #
28
+ def setup!
29
+ return if @setup_complete
30
+
31
+ # Insert loaders before :yml so they have lower priority
32
+ # Bundled defaults first (lowest priority)
33
+ unless loader_registered?(:bundled_defaults)
34
+ Anyway.loaders.insert_before :yml, :bundled_defaults, Loaders::DefaultsLoader
35
+ end
36
+
37
+ # XDG config second (higher priority than bundled defaults)
38
+ unless loader_registered?(:xdg)
39
+ Anyway.loaders.insert_before :yml, :xdg, Loaders::XdgConfigLoader
40
+ end
41
+
42
+ @setup_complete = true
43
+ end
44
+
45
+ # Check if setup has been completed
46
+ #
47
+ # @return [Boolean]
48
+ def setup?
49
+ @setup_complete || false
50
+ end
51
+
52
+ # Reset setup state (mainly for testing)
53
+ def reset!
54
+ @setup_complete = false
55
+ end
56
+
57
+ private
58
+
59
+ def loader_registered?(name)
60
+ Anyway.loaders.registry.any? { |entry| entry.first == name }
61
+ end
62
+ end
63
+ end
64
+
65
+ # Auto-setup when the gem is loaded
66
+ MywayConfig.setup!
data/mkdocs.yml ADDED
@@ -0,0 +1,148 @@
1
+ # MkDocs Configuration for MywayConfig Documentation
2
+ site_name: MywayConfig
3
+ site_description: Configuration management for Ruby applications with XDG support and auto-configuration from YAML
4
+ site_author: Dewayne VanHoozer
5
+ site_url: https://madbomber.github.io/myway_config
6
+ copyright: Copyright &copy; 2025 Dewayne VanHoozer
7
+
8
+ # Repository information
9
+ repo_name: madbomber/myway_config
10
+ repo_url: https://github.com/madbomber/myway_config
11
+ edit_uri: edit/main/docs/
12
+
13
+ # Configuration
14
+ theme:
15
+ name: material
16
+
17
+ # Color scheme
18
+ palette:
19
+ - scheme: default
20
+ primary: teal
21
+ accent: amber
22
+ toggle:
23
+ icon: material/brightness-7
24
+ name: Switch to dark mode
25
+
26
+ - scheme: slate
27
+ primary: teal
28
+ accent: amber
29
+ toggle:
30
+ icon: material/brightness-4
31
+ name: Switch to light mode
32
+
33
+ # Typography
34
+ font:
35
+ text: Roboto
36
+ code: Roboto Mono
37
+
38
+ # Logo and icon
39
+ icon:
40
+ repo: fontawesome/brands/github
41
+ logo: material/cog
42
+
43
+ # Theme features
44
+ features:
45
+ - navigation.instant
46
+ - navigation.tracking
47
+ - navigation.tabs
48
+ - navigation.tabs.sticky
49
+ - navigation.path
50
+ - navigation.indexes
51
+ - navigation.top
52
+ - navigation.footer
53
+ - toc.follow
54
+ - search.suggest
55
+ - search.highlight
56
+ - search.share
57
+ - content.code.copy
58
+ - content.code.annotate
59
+ - content.tabs.link
60
+ - content.tooltips
61
+
62
+ # Plugins
63
+ plugins:
64
+ - search:
65
+ separator: '[\s\-,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
66
+
67
+ # Extensions
68
+ markdown_extensions:
69
+ - abbr
70
+ - admonition
71
+ - attr_list
72
+ - def_list
73
+ - footnotes
74
+ - md_in_html
75
+ - tables
76
+ - toc:
77
+ permalink: true
78
+ title: On this page
79
+ - pymdownx.betterem:
80
+ smart_enable: all
81
+ - pymdownx.caret
82
+ - pymdownx.details
83
+ - pymdownx.emoji:
84
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
85
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
86
+ - pymdownx.highlight:
87
+ anchor_linenums: true
88
+ line_spans: __span
89
+ pygments_lang_class: true
90
+ - pymdownx.inlinehilite
91
+ - pymdownx.keys
92
+ - pymdownx.magiclink:
93
+ repo_url_shorthand: true
94
+ user: madbomber
95
+ repo: myway_config
96
+ normalize_issue_symbols: true
97
+ - pymdownx.mark
98
+ - pymdownx.smartsymbols
99
+ - pymdownx.superfences:
100
+ custom_fences:
101
+ - name: mermaid
102
+ class: mermaid
103
+ format: !!python/name:pymdownx.superfences.fence_code_format
104
+ - pymdownx.tabbed:
105
+ alternate_style: true
106
+ - pymdownx.tasklist:
107
+ custom_checkbox: true
108
+ - pymdownx.tilde
109
+
110
+ # Social media and extra configuration
111
+ extra:
112
+ social:
113
+ - icon: fontawesome/brands/github
114
+ link: https://github.com/madbomber/myway_config
115
+ name: MywayConfig on GitHub
116
+ - icon: fontawesome/solid/gem
117
+ link: https://rubygems.org/gems/myway_config
118
+ name: MywayConfig on RubyGems
119
+
120
+ # Navigation
121
+ nav:
122
+ - Home: index.md
123
+ - Getting Started:
124
+ - getting-started/index.md
125
+ - Installation: getting-started/installation.md
126
+ - Quick Start: getting-started/quick-start.md
127
+ - Guides:
128
+ - guides/index.md
129
+ - Defining Configuration: guides/defining-configuration.md
130
+ - YAML Structure: guides/yaml-structure.md
131
+ - Accessing Values: guides/accessing-values.md
132
+ - Environment Overrides: guides/environment-overrides.md
133
+ - Custom File Loading: guides/custom-file-loading.md
134
+ - Hash-like Behavior: guides/hash-like-behavior.md
135
+ - API Reference:
136
+ - api/index.md
137
+ - MywayConfig::Base: api/base.md
138
+ - ConfigSection: api/config-section.md
139
+ - Loaders: api/loaders.md
140
+ - Examples:
141
+ - examples/index.md
142
+ - Basic Usage: examples/basic-usage.md
143
+ - Rails Integration: examples/rails-integration.md
144
+ - Standalone App: examples/standalone-app.md
145
+ - Development:
146
+ - development/index.md
147
+ - Contributing: development/contributing.md
148
+ - Testing: development/testing.md
@@ -0,0 +1,4 @@
1
+ module MywayConfig
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: myway_config
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Dewayne VanHoozer
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: anyway_config
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '2.0'
26
+ description: MywayConfig extends anyway_config with XDG config file loading, bundled
27
+ defaults, and auto-configuration from YAML. Define your config structure once in
28
+ YAML and access values using method syntax, bracket notation, or Hash-like enumeration.
29
+ email:
30
+ - dewayne@vanhoozer.me
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".envrc"
36
+ - CHANGELOG.md
37
+ - COMMITS.md
38
+ - LICENSE.txt
39
+ - README.md
40
+ - Rakefile
41
+ - docs/api/base.md
42
+ - docs/api/config-section.md
43
+ - docs/api/index.md
44
+ - docs/api/loaders.md
45
+ - docs/development/contributing.md
46
+ - docs/development/index.md
47
+ - docs/development/testing.md
48
+ - docs/examples/basic-usage.md
49
+ - docs/examples/index.md
50
+ - docs/examples/rails-integration.md
51
+ - docs/examples/standalone-app.md
52
+ - docs/getting-started/index.md
53
+ - docs/getting-started/installation.md
54
+ - docs/getting-started/quick-start.md
55
+ - docs/guides/accessing-values.md
56
+ - docs/guides/custom-file-loading.md
57
+ - docs/guides/defining-configuration.md
58
+ - docs/guides/environment-overrides.md
59
+ - docs/guides/hash-like-behavior.md
60
+ - docs/guides/index.md
61
+ - docs/guides/yaml-structure.md
62
+ - docs/index.md
63
+ - lib/myway_config.rb
64
+ - lib/myway_config/base.rb
65
+ - lib/myway_config/config_section.rb
66
+ - lib/myway_config/loaders/defaults_loader.rb
67
+ - lib/myway_config/loaders/xdg_config_loader.rb
68
+ - lib/myway_config/version.rb
69
+ - mkdocs.yml
70
+ - sig/myway_config.rbs
71
+ homepage: https://github.com/madbomber/myway_config
72
+ licenses:
73
+ - MIT
74
+ metadata:
75
+ homepage_uri: https://github.com/madbomber/myway_config
76
+ source_code_uri: https://github.com/madbomber/myway_config
77
+ changelog_uri: https://github.com/madbomber/myway_config/blob/main/CHANGELOG.md
78
+ rubygems_mfa_required: 'true'
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 3.2.0
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubygems_version: 4.0.3
94
+ specification_version: 4
95
+ summary: Configuration management extending anyway_config with XDG support and auto-configuration
96
+ test_files: []