Class: SpaceArchitect::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/space_architect/config.rb

Constant Summary collapse

DEFAULT_DATA =
{
  "version" => 1,
  "base_dir" => "~/architect",
  "default_provider" => "github.com",
  "default_organization" => nil,
  "git_clone_protocol" => "ssh"
}.freeze
EDITABLE_KEYS =
%w[
  base_dir
  spaces_dir
  src_dir
  default_provider
  default_organization
  git_clone_protocol
].freeze
VALID_GIT_CLONE_PROTOCOLS =
%w[ssh https].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env: ENV, path: self.class.default_path(env: env), data: nil) ⇒ Config

Returns a new instance of Config.



35
36
37
38
39
# File 'lib/space_architect/config.rb', line 35

def initialize(env: ENV, path: self.class.default_path(env: env), data: nil)
  @path = Pathname.new(path)
  @env = env
  @data = data ? DEFAULT_DATA.merge(stringify_keys(data)) : DEFAULT_DATA.dup
end

Instance Attribute Details

#dataObject (readonly)

Returns the value of attribute data.



25
26
27
# File 'lib/space_architect/config.rb', line 25

def data
  @data
end

#envObject (readonly)

Returns the value of attribute env.



25
26
27
# File 'lib/space_architect/config.rb', line 25

def env
  @env
end

#pathObject (readonly)

Returns the value of attribute path.



25
26
27
# File 'lib/space_architect/config.rb', line 25

def path
  @path
end

Class Method Details

.default_path(env: ENV) ⇒ Object



27
28
29
# File 'lib/space_architect/config.rb', line 27

def self.default_path(env: ENV)
  XDG.config_home(env: env).join("space-architect", "config.yml")
end

.load(env: ENV, path: default_path(env: env)) ⇒ Object



31
32
33
# File 'lib/space_architect/config.rb', line 31

def self.load(env: ENV, path: default_path(env: env))
  new(env:, path:).load
end

Instance Method Details

#base_dirObject



65
66
67
# File 'lib/space_architect/config.rb', line 65

def base_dir
  Pathname.new(XDG.expand_user(data.fetch("base_dir"), env: env))
end

#default_organizationObject



89
90
91
# File 'lib/space_architect/config.rb', line 89

def default_organization
  normalized_value(data["default_organization"])
end

#default_providerObject



85
86
87
# File 'lib/space_architect/config.rb', line 85

def default_provider
  normalize_provider(data["default_provider"])
end

#ensure_exists!Object



55
56
57
58
# File 'lib/space_architect/config.rb', line 55

def ensure_exists!
  save unless path.exist?
  self
end

#git_clone_protocolObject



93
94
95
96
97
98
99
100
# File 'lib/space_architect/config.rb', line 93

def git_clone_protocol
  protocol = normalized_value(data["git_clone_protocol"]) || "ssh"
  unless VALID_GIT_CLONE_PROTOCOLS.include?(protocol)
    raise Error, "Invalid git_clone_protocol '#{protocol}'. Expected one of: #{VALID_GIT_CLONE_PROTOCOLS.join(', ')}"
  end

  protocol
end

#loadObject



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/space_architect/config.rb', line 41

def load
  @data = if path.exist?
            parsed = YAML.safe_load(path.read, aliases: false) || {}
            unless parsed.is_a?(Hash)
              raise Error, "Config file must contain a YAML mapping: #{path}"
            end

            DEFAULT_DATA.merge(stringify_keys(parsed))
          else
            DEFAULT_DATA.dup
          end
  self
end

#saveObject



60
61
62
63
# File 'lib/space_architect/config.rb', line 60

def save
  AtomicWrite.write(path, YAML.dump(data))
  self
end

#set(key, value) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'lib/space_architect/config.rb', line 102

def set(key, value)
  normalized_key = key.to_s
  unless EDITABLE_KEYS.include?(normalized_key)
    raise InvalidConfigKeyError, "Unknown config key '#{key}'. Expected one of: #{EDITABLE_KEYS.join(', ')}"
  end

  data[normalized_key] = normalize_config_value(normalized_key, value)
  save
end

#spaces_dirObject



69
70
71
72
73
74
# File 'lib/space_architect/config.rb', line 69

def spaces_dir
  value = normalized_value(data["spaces_dir"])
  return base_dir.join("spaces") unless value

  Pathname.new(XDG.expand_user(value, env: env))
end

#src_dirObject



76
77
78
79
80
81
82
83
# File 'lib/space_architect/config.rb', line 76

def src_dir
  return base_dir.join("src") unless data.key?("src_dir")

  value = normalized_value(data["src_dir"])
  return nil unless value

  Pathname.new(XDG.expand_user(value, env: env))
end