File: source.rb

package info (click to toggle)
ruby-librarian 1.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 632 kB
  • sloc: ruby: 6,109; makefile: 11
file content (149 lines) | stat: -rw-r--r-- 3,687 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
require "librarian/error"

module Librarian
  module Config
    class Source

      RAW_KEY_SUFFIX_VALIDITY_PATTERN =
        /\A[A-Z0-9_]+\z/
      CONFIG_KEY_VALIDITY_PATTERN =
        /\A[a-z][a-z0-9\-]+(?:\.[a-z0-9\-]+)*\z/

      class << self
        def raw_key_suffix_validity_pattern
          RAW_KEY_SUFFIX_VALIDITY_PATTERN
        end
        def config_key_validity_pattern
          CONFIG_KEY_VALIDITY_PATTERN
        end
      end

      attr_accessor :adapter_name
      private :adapter_name=

      def initialize(adapter_name, options = { })
        self.adapter_name = adapter_name

        self.forbidden_keys = options.delete(:forbidden_keys) || []
      end

      def [](key)
        load!

        data[key]
      end

      def []=(key, value)
        key_permitted?(key) or raise Error, "key not permitted: #{key.inspect}"
        value_permitted?(key, value) or raise Error, "value for key #{key.inspect} not permitted: #{value.inspect}"

        load!
        if value.nil?
          data.delete(key)
        else
          data[key] = value
        end
        save(data)
      end

      def keys
        load!

        data.keys
      end

    private

      attr_accessor :data, :forbidden_keys

      def load!
        self.data = load unless data
      end

      def key_permitted?(key)
        String === key &&
        config_key_validity_pattern === key &&
        !forbidden_keys.any?{|k| k === key}
      end

      def value_permitted?(key, value)
        return true if value.nil?

        String === value
      end

      def raw_key_valid?(key)
        return false unless key.start_with?(raw_key_prefix)

        suffix = key[raw_key_prefix.size..-1]
        raw_key_suffix_validity_pattern =~ suffix
      end

      def raw_key_suffix_validity_pattern
        self.class.raw_key_suffix_validity_pattern
      end

      def config_key_valid?(key)
        config_key_validity_pattern === key
      end

      def config_key_validity_pattern
        self.class.config_key_validity_pattern
      end

      def raw_key_prefix
        @key_prefix ||= "LIBRARIAN_#{adapter_name.upcase}_"
      end

      def assert_raw_keys_valid!(raw)
        bad_keys = raw.keys.reject{|k| raw_key_valid?(k)}
        unless bad_keys.empty?
          config_path_s = config_path.to_s.inspect
          bad_keys_s = bad_keys.map(&:inspect).join(", ")
          raise Error, "config #{to_s} has bad keys: #{bad_keys_s}"
        end
      end

      def assert_config_keys_valid!(config)
        bad_keys = config.keys.reject{|k| config_key_valid?(k)}
        unless bad_keys.empty?
          bad_keys_s = bad_keys.map(&:inspect).join(", ")
          raise Error, "config has bad keys: #{bad_keys_s}"
        end
      end

      def assert_values_valid!(data)
        bad_data = data.reject{|k, v| String === v}
        bad_keys = bad_data.keys

        unless bad_keys.empty?
          bad_keys_s = bad_keys.map(&:inspect).join(", ")
          raise Error, "config has bad values for keys: #{bad_keys_s}"
        end
      end

      def translate_raw_to_config(raw)
        assert_raw_keys_valid!(raw)
        assert_values_valid!(raw)

        Hash[raw.map do |key, value|
          key = key[raw_key_prefix.size .. -1]
          key = key.downcase.gsub(/__/, ".").gsub(/_/, "-")
          [key, value]
        end]
      end

      def translate_config_to_raw(config)
        assert_config_keys_valid!(config)
        assert_values_valid!(config)

        Hash[config.map do |key, value|
          key = key.gsub(/\./, "__").gsub(/\-/, "_").upcase
          key = "#{raw_key_prefix}#{key}"
          [key, value]
        end]
      end

    end
  end
end