Class: Prick::State
- Inherits:
-
Object
- Object
- Prick::State
- Defined in:
- lib/prick/state.rb
Overview
There is only one State object: Prick.state
FIXME Not how it is done The prick.state file contains the current database, username, and environment. It is controlled by prick(1) but you can set its values by using ‘prick database=asdf
Instance Attribute Summary collapse
-
#database ⇒ Object
Database name.
-
#database_environment ⇒ Object
Environment from PRICK.VERSIONS.
-
#database_prick_version ⇒ Object
Prick version from PRICK.VERSIONS.
-
#database_version ⇒ Object
Project version from PRICK.VERSIONS.
-
#environment_file ⇒ Object
readonly
Environment file.
-
#environments ⇒ Object
readonly
Map from environment name to environment object.
-
#fox_state_file ⇒ Object
readonly
Fox state file.
-
#name ⇒ Object
Used as an identifier and the default database and username.
-
#prick_version ⇒ Object
Version of prick in prick.yml.
-
#project_file ⇒ Object
readonly
Project file.
-
#reflections_file ⇒ Object
readonly
Reflections file.
-
#state_file ⇒ Object
readonly
State file.
-
#title ⇒ Object
Capitalized name of project.
-
#username ⇒ Object
Database owner name.
-
#version ⇒ Object
Project version in prick.yml.
Class Method Summary collapse
-
.connection(&block) ⇒ Object
Superuser connection.
-
.load_yaml(file, mandatory_keys, optional_keys = []) ⇒ Object
To give lib/prick.rb access.
-
.read_yaml(file) ⇒ Object
To give lib/prick.rb access.
Instance Method Summary collapse
-
#bash_environment(all: true) ⇒ Object
Create a bash(1) environment (Hash).
-
#bash_source(vars = nil, scope: nil) ⇒ Object
declared local), or nil (variables are global but not exported).
-
#branch ⇒ Object
Git branch.
-
#clean? ⇒ Boolean
True if the git repository is clean (not modified).
-
#connection(database: nil, username: nil, environment: nil, &block) ⇒ Object
(also: #conn)
Project user (owner) connection.
- #dump ⇒ Object
-
#environment ⇒ Object
Name of current environment.
- #environment=(env) ⇒ Object
- #environment_loaded? ⇒ Boolean
-
#executable_search_path ⇒ Object
Prick executable search_path.
-
#initialize(project_file, environment_file, reflections_file, state_file, fox_state_file) ⇒ State
constructor
A new instance of State.
-
#prick_dir ⇒ Object
Prick project dir.
-
#project_loaded? ⇒ Boolean
True if the configuration files has been loaded.
-
#rev(kind: :long) ⇒ Object
Git revision (commit ID).
- #save_build(success = true) ⇒ Object
-
#save_build_begin ⇒ Object
Save build-start information to PRICK.BUILDS.
- #save_build_end(success, duration) ⇒ Object
-
#save_project(overwrite: false) ⇒ Object
It is an error if the project file exists.
-
#save_state(database = nil, username = nil, environment = nil) ⇒ Object
Used by ‘prick setup’.
-
#save_version ⇒ Object
FIXME: Ugly.
-
#schema_dir ⇒ Object
Prick schema dir.
-
#schema_file ⇒ Object
Schema data file.
- #state_loaded? ⇒ Boolean
Constructor Details
#initialize(project_file, environment_file, reflections_file, state_file, fox_state_file) ⇒ State
Returns a new instance of State.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/prick/state.rb', line 106 def initialize(project_file, environment_file, reflections_file, state_file, fox_state_file) @project_file, @environment_file, @reflections_file, @state_file, @fox_state_file = project_file, environment_file, reflections_file, state_file, fox_state_file @project_loaded = @state_loaded = @environment_loaded = false if @project_file && File.exist?(@project_file) load_project_file load_state_file if @state_file && File.exist?(@state_file) end # FIXME The environment file should be loaded on-demand but it is hard to # do when the environments are accessed through a class-interface load_environment_file if @environment_file && File.exist?(@environment_file) end |
Instance Attribute Details
#database ⇒ Object
Database name. nil if state file is absent
60 61 62 |
# File 'lib/prick/state.rb', line 60 def database @database end |
#database_environment ⇒ Object
Environment from PRICK.VERSIONS. Initialized by #connection
87 88 89 |
# File 'lib/prick/state.rb', line 87 def database_environment @database_environment end |
#database_prick_version ⇒ Object
Prick version from PRICK.VERSIONS. Initialized by #connection
84 85 86 |
# File 'lib/prick/state.rb', line 84 def database_prick_version @database_prick_version end |
#database_version ⇒ Object
Project version from PRICK.VERSIONS. Initialized by #connection
81 82 83 |
# File 'lib/prick/state.rb', line 81 def database_version @database_version end |
#environment_file ⇒ Object (readonly)
Environment file. Default ‘prick.environment’. Note that the file can be absent if the project doesn’t use environments
26 27 28 |
# File 'lib/prick/state.rb', line 26 def environment_file @environment_file end |
#environments ⇒ Object (readonly)
Map from environment name to environment object
67 68 69 |
# File 'lib/prick/state.rb', line 67 def environments @environments end |
#fox_state_file ⇒ Object (readonly)
Fox state file. Default ‘.fox-state.yml’
36 37 38 |
# File 'lib/prick/state.rb', line 36 def fox_state_file @fox_state_file end |
#name ⇒ Object
Used as an identifier and the default database and username
47 48 49 |
# File 'lib/prick/state.rb', line 47 def name @name end |
#prick_version ⇒ Object
Version of prick in prick.yml. Note that this can be different than the current version of prick
57 58 59 |
# File 'lib/prick/state.rb', line 57 def prick_version @prick_version end |
#project_file ⇒ Object (readonly)
Project file. Default ‘prick.yml’
22 23 24 |
# File 'lib/prick/state.rb', line 22 def project_file @project_file end |
#reflections_file ⇒ Object (readonly)
Reflections file. Default ‘schema/reflections.yml’. May be nil if the file is absent
30 31 32 |
# File 'lib/prick/state.rb', line 30 def reflections_file @reflections_file end |
#state_file ⇒ Object (readonly)
State file. Default ‘.prick-state.yml’
33 34 35 |
# File 'lib/prick/state.rb', line 33 def state_file @state_file end |
#title ⇒ Object
Capitalized name of project
50 51 52 |
# File 'lib/prick/state.rb', line 50 def title @title end |
#username ⇒ Object
Database owner name. Typically the same as the database name. nil if database is absent
64 65 66 |
# File 'lib/prick/state.rb', line 64 def username @username end |
#version ⇒ Object
Project version in prick.yml. Can be nil FIXME Can it?
53 54 55 |
# File 'lib/prick/state.rb', line 53 def version @version end |
Class Method Details
.connection(&block) ⇒ Object
Superuser connection. This is a connection to Postgres using the current user’s credentials. It is assumed that the current user has a postgres superuser account with the same name as the user’s. Memoized to connect only once
154 155 156 157 158 159 160 161 |
# File 'lib/prick/state.rb', line 154 def self.connection(&block) @@connection ||= PgConn.new("postgres") if block_given? yield @@connection else @@connection end end |
.load_yaml(file, mandatory_keys, optional_keys = []) ⇒ Object
To give lib/prick.rb access
331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/prick/state.rb', line 331 def self.load_yaml(file, mandatory_keys, optional_keys = []) mandatory_keys = mandatory_keys.map(&:to_s) optional_keys = optional_keys.map(&:to_s) hash = read_yaml(file) or Prick.error "Not a valid YAML file - #{file}" for key in mandatory_keys !hash[key].to_s.empty? or Prick.error "Can't find '#{key}' in #{file}" end (unknown = (hash.keys - mandatory_keys - optional_keys).first) and Prick.error "Illegal key '#{unknown}' in #{file}" hash end |
Instance Method Details
#bash_environment(all: true) ⇒ Object
Create a bash(1) environment (Hash). It is used for in-prick expansion of variables and is also injected into the enviroment of subprocesses
FIXME: Problems with BUNDLE_* variables FIXME Still a problem?
TODO: Explain handling of PRICK_<STANDARD-DIRECTORY>
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/prick/state.rb', line 177 def bash_environment(all: true) @bash_environment ||= begin hash = { "PATH" => Prick.state.executable_search_path } if all hash.merge!({ "PRICK_DIR" => Prick.state.prick_dir, "PRICK_SCHEMADIR" => File.join(Prick.state.prick_dir, SCHEMA_DIR), "PRICK_BINDIR" => File.join(Prick.state.prick_dir, BIN_DIR), "PRICK_LIBEXECDIR" => File.join(Prick.state.prick_dir, LIBEXEC_DIR), "PRICK_VARDIR" => File.join(Prick.state.prick_dir, VAR_DIR), "PRICK_CACHEDIR" => File.join(Prick.state.prick_dir, CACHE_DIR), "PRICK_SPOOLDIR" => File.join(Prick.state.prick_dir, SPOOL_DIR), "PRICK_TMPDIR" => File.join(Prick.state.prick_dir, TMP_DIR), "PRICK_CLONEDIR" => File.join(Prick.state.prick_dir, CLONE_DIR), "PRICK_SPECDIR" => File.join(Prick.state.prick_dir, BIN_DIR), }) end hash.merge!({ "DATABASE" => Prick.state.database, # FIXME: Yt "USERNAME" => Prick.state.username, # FIXME: Yt "ENVIRONMENT" => Prick.state.environment.to_s, # FIXME: Yt except in build.yml parser "PRICK_NAME" => Prick.state.name, "PRICK_TITLE" => Prick.state.title, "PRICK_VERSION" => Prick.state.version, "PRICK_DATABASE" => Prick.state.database, "PRICK_USERNAME" => Prick.state.username, "PRICK_ENVIRONMENT" => Prick.state.environment&.to_s, # may be the empty string }) # PRICK_ENVIRONMENT_* variables. Only defined if the environment is known if !Prick.state.environment.nil? && environments.key?(environment) hash.merge! environments[environment].bash_environment end end end |
#bash_source(vars = nil, scope: nil) ⇒ Object
declared local), or nil (variables are global but not exported)
Only non-text variables are emitted
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/prick/state.rb', line 221 def bash_source(vars = nil, scope: nil) exclude = Array(exclude || []).flatten.map { _1.to_s } case scope when :global; prefix="export " when :local; prefix="local " when nil; prefix="" else raise ArgumentError, "Illegal value for scope: #{scope.inspect}" end vars ||= bash_environment&.keys || [] assignments = [] vars.each { |var| val = bash_environment[var] # next if val =~ /['"\n]/m # We don't quote if val.is_a?(Array) if val.first.is_a?(Array) val = val.map { |v| v.join("\n") }.join("\n") else val = val.join(" ") end end assignments << "#{prefix}#{var}='#{val}'\n" } assignments.join end |
#branch ⇒ Object
Git branch. Lazy-evaluated
90 |
# File 'lib/prick/state.rb', line 90 def branch() @branch ||= Git.branch.current end |
#clean? ⇒ Boolean
True if the git repository is clean (not modified). Lazy-evaluated
101 102 103 104 |
# File 'lib/prick/state.rb', line 101 def clean?() return @clean if defined?(@clean) @clean = Git.clean? end |
#connection(database: nil, username: nil, environment: nil, &block) ⇒ Object Also known as: conn
Project user (owner) connection. Memoized to connect only once. TODO Rename. Also rename self.connection
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 |
# File 'lib/prick/state.rb', line 123 def connection(database: nil, username: nil, environment: nil, &block) if @connection.nil? database ||= self.database username ||= self.username environment ||= self.environment !database.nil? or Prick.error "Can't connect to Postgres - no database specified" # exist_database_environment? or Prick.error "Database '#{database}' is not initialized" @connection = PgConn.new(database, username) # Set database_version/environment/prick members load_database_environment # Set environment if undefined and not overridden by :environment self.environment = environment || Prick.state.environment || environments.key?(database_environment) && database_environment || DEFAULT_ENVIRONMENT end if block_given? yield @connection else @connection end end |
#dump ⇒ Object
308 309 310 311 312 313 314 315 316 317 318 319 |
# File 'lib/prick/state.rb', line 308 def dump puts "State" indent { for method in [ :name, :title, :prick_version, :project_version, :database_version, :database_environment, :database, :username] puts "#{method}: #{self.send method}" end puts "environments:" indent { environments.dump } } end |
#environment ⇒ Object
Name of current environment. If not set in the state file, the enviroment is read from the database when the first connection is established by the #connection method. Use ‘#environments’ to get the corresponding Environment object
73 |
# File 'lib/prick/state.rb', line 73 def environment() @environment end |
#environment=(env) ⇒ Object
74 75 76 77 78 |
# File 'lib/prick/state.rb', line 74 def environment=(env) constrain env, String, nil env.nil? || environments.key?(env) or raise "Illegal environment: '#{env}'" @environment = env end |
#environment_loaded? ⇒ Boolean
44 |
# File 'lib/prick/state.rb', line 44 def environment_loaded? = @environment_loaded |
#executable_search_path ⇒ Object
Prick executable search_path. This includes the bin and libexec directories
167 168 169 |
# File 'lib/prick/state.rb', line 167 def executable_search_path @executable_search_path ||= "#{ENV['PATH']}:#{prick_dir}/#{BIN_DIR}:#{prick_dir}/#{LIBEXEC_DIR}" end |
#prick_dir ⇒ Object
Prick project dir. This is not a constant because prick can change directory through the -C option or the ‘init’ command
16 |
# File 'lib/prick/state.rb', line 16 def prick_dir() @prick_dir ||= Dir.getwd end |
#project_loaded? ⇒ Boolean
True if the configuration files has been loaded
42 |
# File 'lib/prick/state.rb', line 42 def project_loaded? = @project_loaded |
#rev(kind: :long) ⇒ Object
Git revision (commit ID). Lazy-evaluated
93 94 95 96 97 98 |
# File 'lib/prick/state.rb', line 93 def rev(kind: :long) case kind when :short; @rev_short ||= rev()[0...8] when :long; @rev_long ||= Git.id end end |
#save_build(success = true) ⇒ Object
298 299 300 301 302 303 304 305 306 |
# File 'lib/prick/state.rb', line 298 def save_build(success = true) insert_record( "prick.builds", name: name, version: version.to_s, prick: Prick::VERSION, branch: branch, rev: rev(kind: :short), clean: clean?, environment: environment, success: success) end |
#save_build_begin ⇒ Object
Save build-start information to PRICK.BUILDS. It is a nop if PRICK.BUILDS doesn’t exist, this happens on first build in a completely empty database
270 271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/prick/state.rb', line 270 def save_build_begin @build_id = nil # Used by save_build_end if conn.schema.exist_table?("prick", "builds") @build_id = insert_record( "prick.builds", name: name, version: version.to_s, prick: Prick::VERSION, branch: branch, rev: rev(kind: :short), clean: clean?, environment: environment) end # version: version.to_s, prick: prick_version, end |
#save_build_end(success, duration) ⇒ Object
283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/prick/state.rb', line 283 def save_build_end(success, duration) dt = Time.now - TIME if @build_id update_record("prick.builds", @build_id, success: success, duration: duration, prick_duration: dt) else insert_record( "prick.builds", name: name, version: version.to_s, prick: Prick::VERSION, branch: branch, rev: rev(kind: :short), clean: clean?, environment: environment, success: success, duration: duration, prick_duration: dt) end end |
#save_project(overwrite: false) ⇒ Object
It is an error if the project file exists.
249 250 251 252 253 |
# File 'lib/prick/state.rb', line 249 def save_project(overwrite: false) overwrite || !File.exists?(project_file) or Prick.error "Won't overwrite '#{project_file}'" hash = { name: name, title: title, version: version.to_s, prick: Prick::VERSION } save_yaml(project_file, hash) end |
#save_state(database = nil, username = nil, environment = nil) ⇒ Object
Used by ‘prick setup’
261 262 263 264 265 266 |
# File 'lib/prick/state.rb', line 261 def save_state(database = nil, username = nil, environment = nil) database ||= self.database or raise ArgumentError username ||= self.username or raise ArgumentError environment ||= self.environment save_yaml(state_file, database: database, username: username, environment: environment) end |
#save_version ⇒ Object
FIXME: Ugly
256 257 258 |
# File 'lib/prick/state.rb', line 256 def save_version system("sed -i 's/^version:.*/version: #{version.to_s} #{project_file}/'") end |
#schema_dir ⇒ Object
Prick schema dir
19 |
# File 'lib/prick/state.rb', line 19 def schema_dir() @schema_dir ||= File.join(prick_dir, SCHEMA_DIR) end |
#schema_file ⇒ Object
Schema data file. FIXME What is this?
39 |
# File 'lib/prick/state.rb', line 39 def schema_file() SCHEMA_VERSION_PATH end |
#state_loaded? ⇒ Boolean
43 |
# File 'lib/prick/state.rb', line 43 def state_loaded? = @state_loaded |