[DRE-commits] [ruby-asetus] 01/01: Imported Upstream version 0.3.0
Jonas Genannt
genannt at moszumanska.debian.org
Sun Aug 16 11:24:13 UTC 2015
This is an automated email from the git hooks/post-receive script.
genannt pushed a commit to branch master
in repository ruby-asetus.
commit 342837ba46ea535edd89fa9257b52a14d62f5bdb
Author: Jonas Genannt <jonas at brachium-system.net>
Date: Sun Aug 16 12:55:46 2015 +0200
Imported Upstream version 0.3.0
---
.gitignore | 2 +
Gemfile | 3 +
README.md | 74 ++++++++++++++++++++
Rakefile | 47 +++++++++++++
asetus.gemspec | 15 +++++
lib/asetus.rb | 165 +++++++++++++++++++++++++++++++++++++++++++++
lib/asetus/adapter/json.rb | 27 ++++++++
lib/asetus/adapter/toml.rb | 27 ++++++++
lib/asetus/adapter/yaml.rb | 27 ++++++++
lib/asetus/configstruct.rb | 80 ++++++++++++++++++++++
metadata.yml | 54 +++++++++++++++
11 files changed, 521 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d503ae6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+Gemfile.lock
+gems
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..fa75df1
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+
+gemspec
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ce73212
--- /dev/null
+++ b/README.md
@@ -0,0 +1,74 @@
+# Asetus
+Configuration library for ruby with YAML/JSON/TOML backends with unified object
+access
+
+## Install
+```
+ % gem install asetus
+```
+
+## Use
+### Simple
+```
+require 'asetus'
+cfg = Asetus.cfg
+port = cfg.server.port
+user = cfg.auth.user
+pw = cfg.auth.password
+```
+It tried to detect your software name via caller_locations if no ':name'
+argument was given.
+It automatically loads /etc/name/config and ~/.config/name/config and merges
+them together.
+
+### Advanced
+```
+require 'asetus'
+asetus = Asetus.new name: 'mykewlapp',
+ default: {'poop'=>'xyzzy'},
+ adapter: 'yaml',
+ usrdir: '/home/app/config/',
+ sysdir: '/System/config/',
+ load: false
+asetus.default.poop2 = [1, 2, 3, 4]
+asetus.default.starship.poopoers = 42
+asetus.load :user
+if asetus.user.empty?
+ asetus.user = asetus.default
+ asetus.save :user
+end
+asetus.load # load+merges cfg, takes argument :default, :system, :user
+asetus.cfg # merged default + system + user (merged on load)
+asetus.default # default only
+asetus.system # system only
+asetus.user # user only
+```
+
+## Reserved methods
+
+* each - iterate all config keys in current level
+* has_key?(arg) - check if current level has key arg
+* [arg] - fetch arg (useful for non-literal retrieval, instead of using #send)
+* key? - all keys have question mark version reserved, checks if key exists+true (true), exists+false (false), not-exists (nil)
++ all object class methods
+
+## TODO
+
+ * should I add feature to raise on unconfigured/unset?
+ * should I always merge to 'cfg' when default/system/config is set?
+
+## License and Copyright
+
+Copyright 2014-2015 Saku Ytti <saku at ytti.fi>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..7cb8102
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,47 @@
+begin
+ require 'rake/testtask'
+ require 'bundler'
+ #Bundler.setup
+rescue LoadError
+ warn 'bunler missing'
+ exit 42
+end
+
+gemspec = eval(File.read(Dir['*.gemspec'].first))
+file = [gemspec.name, gemspec.version].join('-') + '.gem'
+
+desc 'Validate gemspec'
+task :gemspec do
+ gemspec.validate
+end
+
+desc 'Run minitest'
+task :test do
+ Rake::TestTask.new do |t|
+ t.libs.push "lib"
+ t.test_files = FileList['spec/*_spec.rb']
+ t.verbose = true
+ end
+end
+
+desc 'Build gem'
+task :build do
+ system "gem build #{gemspec.name}.gemspec"
+ FileUtils.mkdir_p 'gems'
+ FileUtils.mv file, 'gems'
+end
+
+desc 'Install gem'
+task :install => :build do
+ system "sudo -E sh -c \'umask 022; gem install gems/#{file}\'"
+end
+
+desc 'Remove gems'
+task :clean do
+ FileUtils.rm_rf 'gems'
+end
+
+desc 'Push to rubygems'
+task :push do
+ system "gem push gems/#{file}"
+end
diff --git a/asetus.gemspec b/asetus.gemspec
new file mode 100644
index 0000000..a5678dc
--- /dev/null
+++ b/asetus.gemspec
@@ -0,0 +1,15 @@
+Gem::Specification.new do |s|
+ s.name = 'asetus'
+ s.version = '0.3.0'
+ s.licenses = ['Apache-2.0']
+ s.platform = Gem::Platform::RUBY
+ s.authors = [ 'Saku Ytti' ]
+ s.email = %w( saku at ytti.fi )
+ s.homepage = 'http://github.com/ytti/asetus'
+ s.summary = 'configuration library'
+ s.description = 'configuration library with object access to YAML/JSON/TOML backends'
+ s.rubyforge_project = s.name
+ s.files = `git ls-files`.split("\n")
+ s.executables = %w( )
+ s.require_path = 'lib'
+end
diff --git a/lib/asetus.rb b/lib/asetus.rb
new file mode 100644
index 0000000..b9719d0
--- /dev/null
+++ b/lib/asetus.rb
@@ -0,0 +1,165 @@
+require_relative 'asetus/configstruct'
+require_relative 'asetus/adapter/yaml'
+require_relative 'asetus/adapter/json'
+require_relative 'asetus/adapter/toml'
+require 'fileutils'
+
+class AsetusError < StandardError; end
+class NoName < AsetusError; end
+class UnknownOption < AsetusError; end
+
+# @example common use case
+# CFGS = Asetus.new :name=>'my_sweet_program' :load=>false # do not load config from filesystem
+# CFGS.default.ssh.port = 22
+# CFGS.default.ssh.hosts = %w(host1.example.com host2.example.com)
+# CFGS.default.auth.user = lana
+# CFGS.default.auth.password = dangerzone
+# CFGS.load # load system config and user config from filesystem and merge with defaults to #cfg
+# raise StandardError, 'edit ~/.config/my_sweet_program/config' if CFGS.create # create user config from default config if no system or user config exists
+# # use the damn thing
+# CFG = CFGS.cfg
+# user = CFG.auth.user
+# password = CFG.auth.password
+# ssh_port = CFG.ssh.port
+# ssh_hosts = CFG.ssh.hosts
+class Asetus
+ CONFIG_FILE = 'config'
+ attr_reader :cfg, :default, :file
+ attr_accessor :system, :user
+
+ class << self
+ def cfg *args
+ new(*args).cfg
+ end
+ end
+
+ # When this is called, by default :system and :user are loaded from
+ # filesystem and merged with defefault, so that user overrides system which
+ # overrides default
+ #
+ # @param [Symbol] level which configuration level to load, by defaukt :all
+ # @return [void]
+ def load level=:all
+ if level == :default or level == :all
+ @cfg = merge @cfg, @default
+ end
+ if level == :system or level == :all
+ @system = load_cfg @sysdir
+ @cfg = merge @cfg, @system
+ end
+ if level == :user or level == :all
+ @user = load_cfg @usrdir
+ @cfg = merge @cfg, @user
+ end
+ end
+
+ # @param [Symbol] level which configuration level to save, by default :user
+ # @return [void]
+ def save level=:user
+ if level == :user
+ save_cfg @usrdir, @user
+ elsif level == :system
+ save_cfg @sysdir, @system
+ end
+ end
+
+ # @example create user config from default config and raise error, if no config was found
+ # raise StandardError, 'edit ~/.config/name/config' if asetus.create
+ # @param [Hash] opts options for Asetus
+ # @option opts [Symbol] :source source to use for settings to save, by defaylt :default
+ # @option opts [Symbol] :destination destinatino to use for settings to save, by default :user
+ # @option opts [boolean] :load load config once saved, by default false
+ # @return [boolean] true if config didn't exist and was created, false if config already exists
+ def create opts={}
+ src = opts.delete :source
+ src ||= :default
+ dst = opts.delete :destination
+ dst ||= :user
+ no_config = false
+ no_config = true if @system.empty? and @user.empty?
+ if no_config
+ src = instance_variable_get '@' + src.to_s
+ instance_variable_set('@'+dst.to_s, src.dup)
+ save dst
+ load if opts.delete :load
+ end
+ no_config
+ end
+
+ private
+
+ # @param [Hash] opts options for Asetus.new
+ # @option opts [String] :name name to use for asetus (/etc/name/, ~/.config/name/) - autodetected if not defined
+ # @option opts [String] :adapter adapter to use 'yaml', 'json' or 'toml' for now
+ # @option opts [String] :usrdir directory for storing user config ~/.config/name/ by default
+ # @option opts [String] :sysdir directory for storing system config /etc/name/ by default
+ # @option opts [String] :cfgfile configuration filename by default CONFIG_FILE
+ # @option opts [Hash] :default default settings to use
+ # @option opts [boolean] :load automatically load+merge system+user config with defaults in #cfg
+ # @option opts [boolean] :key_to_s convert keys to string by calling #to_s for keys
+ def initialize opts={}
+ @name = (opts.delete(:name) or metaname)
+ @adapter = (opts.delete(:adapter) or 'yaml')
+ @usrdir = (opts.delete(:usrdir) or File.join(Dir.home, '.config', @name))
+ @sysdir = (opts.delete(:sysdir) or File.join('/etc', @name))
+ @cfgfile = (opts.delete(:cfgfile) or CONFIG_FILE)
+ @default = ConfigStruct.new opts.delete(:default)
+ @system = ConfigStruct.new
+ @user = ConfigStruct.new
+ @cfg = ConfigStruct.new
+ @load = true
+ @load = opts.delete(:load) if opts.has_key?(:load)
+ @key_to_s = opts.delete(:key_to_s)
+ raise UnknownOption, "option '#{opts}' not recognized" unless opts.empty?
+ load :all if @load
+ end
+
+ def load_cfg dir
+ @file = File.join dir, @cfgfile
+ file = File.read @file
+ ConfigStruct.new(from(@adapter, file), :key_to_s=>@key_to_s)
+ rescue Errno::ENOENT
+ ConfigStruct.new
+ end
+
+ def save_cfg dir, config
+ config = to(@adapter, config)
+ file = File.join dir, @cfgfile
+ FileUtils.mkdir_p dir
+ File.write file, config
+ end
+
+ def merge *configs
+ hash = {}
+ configs.each do |config|
+ hash = hash._asetus_deep_merge config._asetus_to_hash
+ end
+ ConfigStruct.new hash
+ end
+
+ def from adapter, string
+ name = 'from_' + adapter
+ send name, string
+ end
+
+ def to adapter, config
+ name = 'to_' + adapter
+ send name, config
+ end
+
+ def metaname
+ path = caller_locations[-1].path
+ File.basename path, File.extname(path)
+ rescue
+ raise NoName, "can't figure out name, specify explicitly"
+ end
+end
+
+class Hash
+ def _asetus_deep_merge newhash
+ merger = proc do |key, oldval, newval|
+ Hash === oldval && Hash === newval ? oldval.merge(newval, &merger) : newval
+ end
+ merge newhash, &merger
+ end
+end
diff --git a/lib/asetus/adapter/json.rb b/lib/asetus/adapter/json.rb
new file mode 100644
index 0000000..53de794
--- /dev/null
+++ b/lib/asetus/adapter/json.rb
@@ -0,0 +1,27 @@
+class Asetus
+
+ def to_json config
+ Adapter::JSON.to config._asetus_to_hash
+ end
+
+ def from_json json
+ Adapter::JSON.from json
+ end
+
+ class Adapter
+ class JSON
+ class << self
+ def to hash
+ require 'json'
+ ::JSON.pretty_generate hash
+ end
+
+ def from json
+ require 'json'
+ ::JSON.load json
+ end
+ end
+ end
+ end
+
+end
diff --git a/lib/asetus/adapter/toml.rb b/lib/asetus/adapter/toml.rb
new file mode 100644
index 0000000..d7fbd29
--- /dev/null
+++ b/lib/asetus/adapter/toml.rb
@@ -0,0 +1,27 @@
+class Asetus
+
+ def to_toml config
+ Adapter::TOML.to config._asetus_to_hash
+ end
+
+ def from_toml toml
+ Adapter::TOML.from toml
+ end
+
+ class Adapter
+ class TOML
+ class << self
+ def to hash
+ require 'toml'
+ ::TOML::Generator.new(hash).body
+ end
+
+ def from toml
+ require 'toml'
+ ::TOML.load toml
+ end
+ end
+ end
+ end
+
+end
diff --git a/lib/asetus/adapter/yaml.rb b/lib/asetus/adapter/yaml.rb
new file mode 100644
index 0000000..c910a0c
--- /dev/null
+++ b/lib/asetus/adapter/yaml.rb
@@ -0,0 +1,27 @@
+class Asetus
+
+ def to_yaml config
+ Adapter::YAML.to config._asetus_to_hash
+ end
+
+ def from_yaml yaml
+ Adapter::YAML.from yaml
+ end
+
+ class Adapter
+ class YAML
+ class << self
+ def to hash
+ require 'yaml'
+ ::YAML.dump hash
+ end
+
+ def from yaml
+ require 'yaml'
+ ::YAML.load yaml
+ end
+ end
+ end
+ end
+
+end
diff --git a/lib/asetus/configstruct.rb b/lib/asetus/configstruct.rb
new file mode 100644
index 0000000..d73bba4
--- /dev/null
+++ b/lib/asetus/configstruct.rb
@@ -0,0 +1,80 @@
+class Asetus
+ class ConfigStruct
+
+ def _asetus_to_hash
+ hash = {}
+ @cfg.each do |key, value|
+ if value.class == ConfigStruct
+ value = value._asetus_to_hash
+ end
+ key = key.to_s if @key_to_s
+ hash[key] = value
+ end
+ hash
+ end
+
+ def empty?
+ @cfg.empty?
+ end
+
+ def each &block
+ @cfg.each(&block)
+ end
+
+ def keys
+ @cfg.keys
+ end
+
+ def has_key? key
+ @cfg.has_key? key
+ end
+
+ private
+
+ def initialize hash=nil, opts={}
+ @key_to_s = opts.delete :key_to_s
+ @cfg = hash ? _asetus_from_hash(hash) : {}
+ end
+
+ def method_missing name, *args, &block
+ name = name.to_s
+ name = args.shift if name[0..1] == '[]' # asetus.cfg['foo']
+ arg = args.first
+ if name[-1..-1] == '?' # asetus.cfg.foo.bar?
+ if @cfg.has_key? name[0..-2]
+ @cfg[name[0..-2]]
+ else
+ nil
+ end
+ elsif name[-1..-1] == '=' # asetus.cfg.foo.bar = 'quux'
+ _asetus_set name[0..-2], arg
+ else
+ _asetus_get name, arg # asetus.cfg.foo.bar
+ end
+ end
+
+ def _asetus_set key, value
+ @cfg[key] = value
+ end
+
+ def _asetus_get key, value
+ if @cfg.has_key? key
+ @cfg[key]
+ else
+ @cfg[key] = ConfigStruct.new
+ end
+ end
+
+ def _asetus_from_hash hash
+ cfg = {}
+ hash.each do |key, value|
+ if value.class == Hash
+ value = ConfigStruct.new value, :key_to_s=>@key_to_s
+ end
+ cfg[key] = value
+ end
+ cfg
+ end
+
+ end
+end
diff --git a/metadata.yml b/metadata.yml
new file mode 100644
index 0000000..3883b63
--- /dev/null
+++ b/metadata.yml
@@ -0,0 +1,54 @@
+--- !ruby/object:Gem::Specification
+name: asetus
+version: !ruby/object:Gem::Version
+ version: 0.3.0
+platform: ruby
+authors:
+- Saku Ytti
+autorequire:
+bindir: bin
+cert_chain: []
+date: 2015-03-08 00:00:00.000000000 Z
+dependencies: []
+description: configuration library with object access to YAML/JSON/TOML backends
+email:
+- saku at ytti.fi
+executables: []
+extensions: []
+extra_rdoc_files: []
+files:
+- ".gitignore"
+- Gemfile
+- README.md
+- Rakefile
+- asetus.gemspec
+- lib/asetus.rb
+- lib/asetus/adapter/json.rb
+- lib/asetus/adapter/toml.rb
+- lib/asetus/adapter/yaml.rb
+- lib/asetus/configstruct.rb
+homepage: http://github.com/ytti/asetus
+licenses:
+- Apache-2.0
+metadata: {}
+post_install_message:
+rdoc_options: []
+require_paths:
+- lib
+required_ruby_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: '0'
+required_rubygems_version: !ruby/object:Gem::Requirement
+ requirements:
+ - - ">="
+ - !ruby/object:Gem::Version
+ version: '0'
+requirements: []
+rubyforge_project: asetus
+rubygems_version: 2.2.2
+signing_key:
+specification_version: 4
+summary: configuration library
+test_files: []
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-asetus.git
More information about the Pkg-ruby-extras-commits
mailing list