From a4cc284ab111e945ef7091cc6677ef656a9a5e23 Mon Sep 17 00:00:00 2001 From: VetheonGames Date: Fri, 13 Oct 2023 21:16:43 -0600 Subject: [PATCH] upload all the things --- Gemfile | 12 +- Gemfile.lock | 70 ++++++++ Rakefile | 6 +- bin/console | 2 +- ConfigMan.gemspec => configman.gemspec | 19 +-- lib/ConfigMan.rb | 8 - lib/configman.rb | 158 ++++++++++++++++++ lib/configman/modules/api.rb | 15 ++ lib/configman/modules/cache.rb | 15 ++ lib/configman/modules/database.rb | 17 ++ lib/configman/modules/email.rb | 17 ++ lib/configman/modules/filestorage.rb | 15 ++ lib/configman/modules/localization.rb | 14 ++ lib/configman/modules/logging.rb | 15 ++ lib/configman/parsers/ini.rb | 38 +++++ lib/configman/parsers/json.rb | 44 +++++ lib/configman/parsers/xml.rb | 47 ++++++ lib/configman/parsers/yaml.rb | 37 ++++ lib/{ConfigMan => configman}/version.rb | 2 +- sig/{ConfigMan.rbs => configman.rbs} | 0 spec/{ConfigMan_spec.rb => configman_spec.rb} | 4 +- spec/spec_helper.rb | 4 +- 22 files changed, 526 insertions(+), 33 deletions(-) create mode 100644 Gemfile.lock rename ConfigMan.gemspec => configman.gemspec (60%) delete mode 100644 lib/ConfigMan.rb create mode 100644 lib/configman.rb create mode 100644 lib/configman/modules/api.rb create mode 100644 lib/configman/modules/cache.rb create mode 100644 lib/configman/modules/database.rb create mode 100644 lib/configman/modules/email.rb create mode 100644 lib/configman/modules/filestorage.rb create mode 100644 lib/configman/modules/localization.rb create mode 100644 lib/configman/modules/logging.rb create mode 100644 lib/configman/parsers/ini.rb create mode 100644 lib/configman/parsers/json.rb create mode 100644 lib/configman/parsers/xml.rb create mode 100644 lib/configman/parsers/yaml.rb rename lib/{ConfigMan => configman}/version.rb (72%) rename sig/{ConfigMan.rbs => configman.rbs} (100%) rename spec/{ConfigMan_spec.rb => configman_spec.rb} (70%) diff --git a/Gemfile b/Gemfile index 7832cdb..82f0f78 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,16 @@ # frozen_string_literal: true -source "https://rubygems.org" +source 'https://rubygems.org' # Specify your gem's dependencies in ConfigMan.gemspec gemspec -gem "rake", "~> 13.0" +gem 'rake', '~> 13.0' -gem "rspec", "~> 3.0" +gem 'rspec', '~> 3.0' -gem "rubocop", "~> 1.21" +gem 'rubocop', '~> 1.21' + +gem "rexml", "~> 3.2" + +gem "inifile", "~> 3.0" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..b231555 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,70 @@ +PATH + remote: . + specs: + configman (1.0.0) + inifile + json + yaml + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + base64 (0.1.1) + diff-lcs (1.5.0) + inifile (3.0.0) + json (2.6.3) + language_server-protocol (3.17.0.3) + parallel (1.23.0) + parser (3.2.2.4) + ast (~> 2.4.1) + racc + racc (1.7.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.8.2) + rexml (3.2.6) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.6) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.1) + rubocop (1.57.1) + base64 (~> 0.1.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.4) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + ruby-progressbar (1.13.0) + unicode-display_width (2.5.0) + yaml (0.2.1) + +PLATFORMS + x86_64-linux + +DEPENDENCIES + configman! + inifile (~> 3.0) + rake (~> 13.0) + rexml (~> 3.2) + rspec (~> 3.0) + rubocop (~> 1.21) + +BUNDLED WITH + 2.4.19 diff --git a/Rakefile b/Rakefile index cca7175..4964751 100644 --- a/Rakefile +++ b/Rakefile @@ -1,11 +1,11 @@ # frozen_string_literal: true -require "bundler/gem_tasks" -require "rspec/core/rake_task" +require 'bundler/gem_tasks' +require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -require "rubocop/rake_task" +require 'rubocop/rake_task' RuboCop::RakeTask.new diff --git a/bin/console b/bin/console index 6c71506..26fdec2 100755 --- a/bin/console +++ b/bin/console @@ -2,7 +2,7 @@ # frozen_string_literal: true require "bundler/setup" -require "ConfigMan" +require "configman" # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. diff --git a/ConfigMan.gemspec b/configman.gemspec similarity index 60% rename from ConfigMan.gemspec rename to configman.gemspec index 0932425..6eca2d7 100644 --- a/ConfigMan.gemspec +++ b/configman.gemspec @@ -1,24 +1,20 @@ # frozen_string_literal: true -require_relative 'lib/ConfigMan/version' +require_relative 'lib/configman/version' Gem::Specification.new do |spec| - spec.name = 'ConfigMan' + spec.name = 'configman' spec.version = ConfigMan::VERSION spec.authors = ['PixelRidge Softworks'] spec.email = ['vetheon@pixelridgesoftworks.com'] spec.summary = 'A Ruby Gem for automating your configs!' - spec.description = 'TODO: Write a longer description or delete this line.' - spec.homepage = "TODO: Put your gem's website or public repo URL here." - spec.license = 'MIT' - spec.required_ruby_version = '>= 2.6.0' - - spec.metadata['allowed_push_host'] = "TODO: Set to your gem server 'https://example.com'" + spec.homepage = 'https://git.pixelridgesoftworks.com/PixelRidge-Softworks/ConfigMan' + spec.license = 'PixelRidge-BEGPULSE' + spec.required_ruby_version = '>= 3.2.2' spec.metadata['homepage_uri'] = spec.homepage - spec.metadata['source_code_uri'] = "TODO: Put your gem's public repo URL here." - spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here." + spec.metadata['source_code_uri'] = 'https://git.pixelridgesoftworks.com/PixelRidge-Softworks/ConfigMan' # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the RubyGem that have been added into git. @@ -28,12 +24,11 @@ Gem::Specification.new do |spec| f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile]) end end - spec.bindir = 'exe' - spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] # Uncomment to register a new dependency of your gem # spec.add_dependency "example-gem", "~> 1.0" + spec.add_dependency 'inifile' # For more information and examples about making a new gem, check out our # guide at: https://bundler.io/guides/creating_gem.html diff --git a/lib/ConfigMan.rb b/lib/ConfigMan.rb deleted file mode 100644 index 3247aa1..0000000 --- a/lib/ConfigMan.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -require_relative "ConfigMan/version" - -module ConfigMan - class Error < StandardError; end - # Your code goes here... -end diff --git a/lib/configman.rb b/lib/configman.rb new file mode 100644 index 0000000..0f4f315 --- /dev/null +++ b/lib/configman.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true + +require_relative 'configman/version' +require_relative 'configman/parsers/json' +require_relative 'configman/parsers/ini' +require_relative 'configman/parsers/xml' +require_relative 'configman/parsers/yaml' + +module ConfigMan + class Error < StandardError; end + + @config_values = {} + @used_modules = [] + @loaded_parser = nil + @custom_modules = [] + + # Initialize with default or provided options + def self.init(options = {}) + @config_values.merge!(options) + end + + # register any custom modules the user provides + def self.register_module(file_path) + raise ArgumentError, "File not found: #{file_path}" unless File.exist?(file_path) + + require file_path + + module_name = File.basename(file_path, '.rb').capitalize + mod_class = Object.const_get(module_name) + + unless mod_class.respond_to?(:populate_defaults) + raise ArgumentError, "Custom module must implement a 'populate_defaults' method" + end + + @custom_modules << mod_class + end + + # Setup ConfigMan with presets + def self.setup(default_modules, custom_options) + final_config = {} + + # Populate defaults from built-in modules + default_modules.each do |mod| + mod_class = Object.const_get("ConfigMan::Modules::#{mod.capitalize}") + final_config.merge!(mod_class.populate_defaults) + end + + # Populate defaults from custom modules + @custom_modules.each do |mod_class| + final_config.merge!(mod_class.populate_defaults) + end + + # Add custom options + final_config.merge!(custom_options) + + # Write to the config file using the appropriate parser + parser_module = Object.const_get("ConfigMan::Parsers::#{@loaded_parser.upcase}") + parser_module.write(final_config) + end + + # Generate a .config file in the working directory + def self.generate_config_file(final_config) + File.open('.config', 'w') do |file| + case @loaded_parser + when 'json' + file.write(JSON.pretty_generate(final_config)) + when 'yaml' + require 'yaml' + file.write(final_config.to_yaml) + when 'xml' + require 'rexml/document' + xml = REXML::Document.new + xml.add_element('config', final_config) + formatter = REXML::Formatters::Pretty.new + formatter.write(xml, file) + when 'ini' + require 'inifile' + ini = IniFile.new + ini['default'] = final_config + file.write(ini.to_s) + else + file.write(JSON.pretty_generate(final_config)) # Default to JSON + end + end + end + + # Lazy loading of modules and parsers + def self.load_modules(module_names) + module_names.each do |module_name| + if %w[json ini xml yaml].include?(module_name.downcase) + # It's a parser + require_relative "configman/parsers/#{module_name.downcase}" + else + # It's a regular module + require_relative "configman/modules/#{module_name.downcase}" + end + @used_modules << module_name.downcase + end + end + + # Cleanup unused modules + def self.cleanup_unused_modules + # List of all available modules + all_modules = %w[database logging api ini yaml] + + # Calculate modules to remove + remove_modules = all_modules - @used_modules + + # Remove unnecessary modules + remove_modules.each do |mod| + module_path = File.join(__dir__, 'modules', "#{mod}.rb") + File.delete(module_path) if File.exist?(module_path) + end + end + + # Load configurations from the .config file + def self.load + config_file_path = File.join(Dir.pwd, '.config') + parsed_config = send_to_parser(config_file_path) + # Assuming send_to_parser delegates to the correct parser and returns a hash + + parsed_config.each do |key, value| + define_singleton_method(key) do + value + end + end + end + + # Delegate to the appropriate parser to parse the file + def self.send_to_parser(file_path) + raise ArgumentError, 'No parser loaded' unless @loaded_parser + + parser_module = Object.const_get("ConfigMan::Parsers::#{@loaded_parser.upcase}") + + raise ArgumentError, "Invalid parser: #{@loaded_parser}" unless parser_module.respond_to?(:parse) + + parsed_config = parser_module.parse(file_path) + @config_values.merge!(parsed_config) + end + + def self.fetch(key) + @config_values[key] || raise(%(Configuration key "#{key}" not found.)) + end + + # Handle undefined methods to fetch config values + def self.method_missing(method_name, *args, &block) + if @config_values.key?(method_name) + @config_values[method_name] + else + super + end + end + + # Respond to missing methods + def self.respond_to_missing?(method_name, include_private = false) + @config_values.key?(method_name) || super + end +end diff --git a/lib/configman/modules/api.rb b/lib/configman/modules/api.rb new file mode 100644 index 0000000..78ed421 --- /dev/null +++ b/lib/configman/modules/api.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ConfigMan + module Modules + module API + def self.populate_defaults + { + 'api_endpoint' => 'https://api.example.com', + 'api_key' => 'your_api_key_here', + 'rate_limit' => 1000 + } + end + end + end +end diff --git a/lib/configman/modules/cache.rb b/lib/configman/modules/cache.rb new file mode 100644 index 0000000..e470a4d --- /dev/null +++ b/lib/configman/modules/cache.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ConfigMan + module Modules + module Cache + def self.populate_defaults + { + 'cache_type' => 'Redis', + 'host' => 'localhost', + 'port' => 6379 + } + end + end + end +end diff --git a/lib/configman/modules/database.rb b/lib/configman/modules/database.rb new file mode 100644 index 0000000..7cc02bd --- /dev/null +++ b/lib/configman/modules/database.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module ConfigMan + module Modules + module Database + def self.populate_defaults + { + 'db_host' => 'localhost', + 'db_port' => 3306, + 'db_user' => 'root', + 'db_password' => 'password', + 'db_name' => 'my_database' + } + end + end + end +end diff --git a/lib/configman/modules/email.rb b/lib/configman/modules/email.rb new file mode 100644 index 0000000..bf87ea4 --- /dev/null +++ b/lib/configman/modules/email.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module ConfigMan + module Modules + module Email + def self.populate_defaults + { + 'smtp_server' => 'smtp.example.com', + 'smtp_port' => 587, + 'smtp_user' => 'user@example.com', + 'smtp_password' => 'password_here', + 'smtp_protocol' => 'SSL/TLS' + } + end + end + end +end diff --git a/lib/configman/modules/filestorage.rb b/lib/configman/modules/filestorage.rb new file mode 100644 index 0000000..6951473 --- /dev/null +++ b/lib/configman/modules/filestorage.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ConfigMan + module Modules + module FileStorage + def self.populate_defaults + { + 'storage_type' => 'local', + 'cloud_provider' => 'none', + 'local_path' => '/path/to/storage' + } + end + end + end +end diff --git a/lib/configman/modules/localization.rb b/lib/configman/modules/localization.rb new file mode 100644 index 0000000..f074984 --- /dev/null +++ b/lib/configman/modules/localization.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module ConfigMan + module Modules + module Localization + def self.populate_defaults + { + 'language' => 'en', + 'time_zone' => 'UTC' + } + end + end + end +end diff --git a/lib/configman/modules/logging.rb b/lib/configman/modules/logging.rb new file mode 100644 index 0000000..9ad32b5 --- /dev/null +++ b/lib/configman/modules/logging.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ConfigMan + module Modules + module Logging + def self.populate_defaults + { + 'log_level' => 'info', + 'log_file' => 'application.log', + 'log_rotation' => 'daily' + } + end + end + end +end diff --git a/lib/configman/parsers/ini.rb b/lib/configman/parsers/ini.rb new file mode 100644 index 0000000..6722c7e --- /dev/null +++ b/lib/configman/parsers/ini.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'inifile' + +module ConfigMan + module Parsers + module INI + CONFIG_FILE_PATH = File.join(Dir.pwd, '.config').freeze + + # Parse the .config file and return a hash of the configuration values + def self.parse(file_path) + raise ArgumentError, "File not found: #{file_path}" unless File.exist?(file_path) + + ini = IniFile.load(file_path) + parsed_config = ini.to_h + + raise ArgumentError, "Invalid INI format in #{file_path}" unless parsed_config.is_a?(Hash) + + parsed_config + end + + def self.update(key, new_value) + existing_config = parse(CONFIG_FILE_PATH) + section, key = key.split('.', 2) + existing_config[section] ||= {} + existing_config[section][key] = new_value + + ini = IniFile.new(content: existing_config) + ini.write(filename: CONFIG_FILE_PATH) + end + + def self.write(config_hash) + ini = IniFile.new(content: config_hash) + ini.write(filename: CONFIG_FILE_PATH) + end + end + end +end diff --git a/lib/configman/parsers/json.rb b/lib/configman/parsers/json.rb new file mode 100644 index 0000000..4762d46 --- /dev/null +++ b/lib/configman/parsers/json.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require 'json' + +module ConfigMan + module Parsers + module JSON + CONFIG_FILE_PATH = File.join(Dir.pwd, '.config').freeze + + # Parse the .config file and return a hash of the configuration values + def self.parse(file_path) + raise ArgumentError, "File not found: #{file_path}" unless File.exist?(file_path) + + @file_path = file_path + + file_content = File.read(file_path) + parsed_config = ::JSON.parse(file_content) + + raise ArgumentError, "Invalid JSON format in #{file_path}" unless parsed_config.is_a?(Hash) + + parsed_config + end + + def self.update(key, new_value) + # Read existing config + existing_config = parse + + # Update the value + existing_config[key] = new_value + + # Write the updated config back to the file + File.open(CONFIG_FILE_PATH, 'w') do |file| + file.write(::JSON.pretty_generate(existing_config)) + end + end + + def self.write(config_hash) + File.open(CONFIG_FILE_PATH, 'w') do |file| + file.write(::JSON.pretty_generate(config_hash)) + end + end + end + end +end diff --git a/lib/configman/parsers/xml.rb b/lib/configman/parsers/xml.rb new file mode 100644 index 0000000..0c2acab --- /dev/null +++ b/lib/configman/parsers/xml.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'rexml/document' + +module ConfigMan + module Parsers + module XML + CONFIG_FILE_PATH = File.join(Dir.pwd, '.config').freeze + + # Parse the .config file and return a hash of the configuration values + def self.parse(file_path) + raise ArgumentError, "File not found: #{file_path}" unless File.exist?(file_path) + + xml_file = File.new(file_path) + document = REXML::Document.new(xml_file) + parsed_config = {} + + document.elements.each('config/*') do |element| + parsed_config[element.name] = element.text + end + + raise ArgumentError, "Invalid XML format in #{file_path}" unless parsed_config.is_a?(Hash) + + parsed_config + end + + def self.update(key, new_value) + existing_config = parse(CONFIG_FILE_PATH) + existing_config[key] = new_value + + doc = REXML::Document.new + doc.add_element('config') + existing_config.each { |k, v| doc.root.add_element(k).text = v } + + File.open(CONFIG_FILE_PATH, 'w') { |file| doc.write(file) } + end + + def self.write(config_hash) + doc = REXML::Document.new + doc.add_element('config') + config_hash.each { |k, v| doc.root.add_element(k).text = v } + + File.open(CONFIG_FILE_PATH, 'w') { |file| doc.write(file) } + end + end + end +end diff --git a/lib/configman/parsers/yaml.rb b/lib/configman/parsers/yaml.rb new file mode 100644 index 0000000..ac3f85a --- /dev/null +++ b/lib/configman/parsers/yaml.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'yaml' + +module ConfigMan + module Parsers + module YAML + CONFIG_FILE_PATH = File.join(Dir.pwd, '.config').freeze + + # Parse the .config file and return a hash of the configuration values + def self.parse(file_path) + raise ArgumentError, "File not found: #{file_path}" unless File.exist?(file_path) + + parsed_config = ::YAML.load_file(file_path) + + raise ArgumentError, "Invalid YAML format in #{file_path}" unless parsed_config.is_a?(Hash) + + parsed_config + end + + def self.update(key, new_value) + existing_config = parse(CONFIG_FILE_PATH) + existing_config[key] = new_value + + File.open(CONFIG_FILE_PATH, 'w') do |file| + file.write(existing_config.to_yaml) + end + end + + def self.write(config_hash) + File.open(CONFIG_FILE_PATH, 'w') do |file| + file.write(config_hash.to_yaml) + end + end + end + end +end diff --git a/lib/ConfigMan/version.rb b/lib/configman/version.rb similarity index 72% rename from lib/ConfigMan/version.rb rename to lib/configman/version.rb index 051a17d..3eedee2 100644 --- a/lib/ConfigMan/version.rb +++ b/lib/configman/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ConfigMan - VERSION = "0.1.0" + VERSION = '1.0.0' end diff --git a/sig/ConfigMan.rbs b/sig/configman.rbs similarity index 100% rename from sig/ConfigMan.rbs rename to sig/configman.rbs diff --git a/spec/ConfigMan_spec.rb b/spec/configman_spec.rb similarity index 70% rename from spec/ConfigMan_spec.rb rename to spec/configman_spec.rb index 82b1cd6..115f489 100644 --- a/spec/ConfigMan_spec.rb +++ b/spec/configman_spec.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true RSpec.describe ConfigMan do - it "has a version number" do + it 'has a version number' do expect(ConfigMan::VERSION).not_to be nil end - it "does something useful" do + it 'does something useful' do expect(false).to eq(true) end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 81c8d9c..4d3d8cd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -require "ConfigMan" +require 'configman' RSpec.configure do |config| # Enable flags like --only-failures and --next-failure - config.example_status_persistence_file_path = ".rspec_status" + config.example_status_persistence_file_path = '.rspec_status' # Disable RSpec exposing methods globally on `Module` and `main` config.disable_monkey_patching!