[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