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.
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.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/prick/state.rb', line 105 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
59 60 61 |
# File 'lib/prick/state.rb', line 59 def database @database end |
#database_environment ⇒ Object
Environment from PRICK.VERSIONS. Initialized by #connection
86 87 88 |
# File 'lib/prick/state.rb', line 86 def database_environment @database_environment end |
#database_prick_version ⇒ Object
Prick version from PRICK.VERSIONS. Initialized by #connection
83 84 85 |
# File 'lib/prick/state.rb', line 83 def database_prick_version @database_prick_version end |
#database_version ⇒ Object
Project version from PRICK.VERSIONS. Initialized by #connection
80 81 82 |
# File 'lib/prick/state.rb', line 80 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
25 26 27 |
# File 'lib/prick/state.rb', line 25 def environment_file @environment_file end |
#environments ⇒ Object (readonly)
Map from environment name to environment object
66 67 68 |
# File 'lib/prick/state.rb', line 66 def environments @environments end |
#fox_state_file ⇒ Object (readonly)
Fox state file. Default ‘.fox-state.yml’
35 36 37 |
# File 'lib/prick/state.rb', line 35 def fox_state_file @fox_state_file end |
#name ⇒ Object
Used as an identifier and the default database and username
46 47 48 |
# File 'lib/prick/state.rb', line 46 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
56 57 58 |
# File 'lib/prick/state.rb', line 56 def prick_version @prick_version end |
#project_file ⇒ Object (readonly)
Project file. Default ‘prick.yml’
21 22 23 |
# File 'lib/prick/state.rb', line 21 def project_file @project_file end |
#reflections_file ⇒ Object (readonly)
Reflections file. Default ‘schema/reflections.yml’. May be nil if the file is absent
29 30 31 |
# File 'lib/prick/state.rb', line 29 def reflections_file @reflections_file end |
#state_file ⇒ Object (readonly)
State file. Default ‘.prick-state.yml’
32 33 34 |
# File 'lib/prick/state.rb', line 32 def state_file @state_file end |
#title ⇒ Object
Capitalized name of project
49 50 51 |
# File 'lib/prick/state.rb', line 49 def title @title end |
#username ⇒ Object
Database owner name. Typically the same as the database name. nil if database is absent
63 64 65 |
# File 'lib/prick/state.rb', line 63 def username @username end |
#version ⇒ Object
Project version in prick.yml. Can be nil FIXME Can it?
52 53 54 |
# File 'lib/prick/state.rb', line 52 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
153 154 155 156 157 158 159 160 |
# File 'lib/prick/state.rb', line 153 def self.connection(&block) @@connection ||= PgConn.new("postgres") if block_given? yield @@connection else @@connection end 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>
176 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 |
# File 'lib/prick/state.rb', line 176 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
220 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 |
# File 'lib/prick/state.rb', line 220 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
89 |
# File 'lib/prick/state.rb', line 89 def branch() @branch ||= Git.branch.current end |
#clean? ⇒ Boolean
True if the git repository is clean (not modified). Lazy-evaluated
100 101 102 103 |
# File 'lib/prick/state.rb', line 100 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
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 |
# File 'lib/prick/state.rb', line 122 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
307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/prick/state.rb', line 307 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
72 |
# File 'lib/prick/state.rb', line 72 def environment() @environment end |
#environment=(env) ⇒ Object
73 74 75 76 77 |
# File 'lib/prick/state.rb', line 73 def environment=(env) constrain env, String, nil env.nil? || environments.key?(env) or raise "Illegal environment: '#{env}'" @environment = env end |
#environment_loaded? ⇒ Boolean
43 |
# File 'lib/prick/state.rb', line 43 def environment_loaded? = @environment_loaded |
#executable_search_path ⇒ Object
Prick executable search_path. This includes the bin and libexec directories
166 167 168 |
# File 'lib/prick/state.rb', line 166 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
15 |
# File 'lib/prick/state.rb', line 15 def prick_dir() @prick_dir ||= Dir.getwd end |
#project_loaded? ⇒ Boolean
True if the configuration files has been loaded
41 |
# File 'lib/prick/state.rb', line 41 def project_loaded? = @project_loaded |
#rev(kind: :long) ⇒ Object
Git revision (commit ID). Lazy-evaluated
92 93 94 95 96 97 |
# File 'lib/prick/state.rb', line 92 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
297 298 299 300 301 302 303 304 305 |
# File 'lib/prick/state.rb', line 297 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
269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/prick/state.rb', line 269 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
282 283 284 285 286 287 288 289 290 291 292 293 294 295 |
# File 'lib/prick/state.rb', line 282 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.
248 249 250 251 252 |
# File 'lib/prick/state.rb', line 248 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’
260 261 262 263 264 265 |
# File 'lib/prick/state.rb', line 260 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
255 256 257 |
# File 'lib/prick/state.rb', line 255 def save_version system("sed -i 's/^version:.*/version: #{version.to_s} #{project_file}/'") end |
#schema_dir ⇒ Object
Prick schema dir
18 |
# File 'lib/prick/state.rb', line 18 def schema_dir() @schema_dir ||= File.join(prick_dir, SCHEMA_DIR) end |
#schema_file ⇒ Object
Schema data file. FIXME What is this?
38 |
# File 'lib/prick/state.rb', line 38 def schema_file() SCHEMA_VERSION_PATH end |
#state_loaded? ⇒ Boolean
42 |
# File 'lib/prick/state.rb', line 42 def state_loaded? = @state_loaded |