prick 0.28.0 → 0.28.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/TODO +1 -0
- data/exe/prick +0 -4
- data/lib/builder/batch.rb +2 -2
- data/lib/builder/node.rb +23 -19
- data/lib/builder/parser.rb +109 -84
- data/lib/local/command.rb +15 -17
- data/lib/prick/constants.rb +10 -2
- data/lib/prick/state.rb +29 -0
- data/lib/prick/version.rb +1 -1
- data/lib/subcommand/prick-build.rb +1 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10bf0db9a65cd8441d8f17ea9ad055f177d49508f2445ee733722fcc0fb5c6dc
|
4
|
+
data.tar.gz: 693a602c5f57b6bdd97cdefa00c69a0c517cd54e4b32e2d10657fa1c8cfb8949
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ec3e792b312d572d9eb65feb3c595d94ec944b9854f12c9f16a805dfce24a45d0be6fe923c02fc1bf57c9a3ce0d6b221c28eaeaea5a1ab1a0f044e228a07b5e
|
7
|
+
data.tar.gz: a0cc6eb39133fbfc7eef170a173378bd685a3f43315ac633748dc1fafa02589dae100d1fe8f30ab4687a175e3d8a13d0fca793245fbb10fb2297fed5d8e4c659
|
data/TODO
CHANGED
data/exe/prick
CHANGED
data/lib/builder/batch.rb
CHANGED
@@ -32,8 +32,8 @@ module Prick
|
|
32
32
|
super {
|
33
33
|
begin
|
34
34
|
sql = []
|
35
|
-
# A SQL batch allows the first node to be an
|
36
|
-
if nodes.first.is_a?(
|
35
|
+
# A SQL batch allows the first node to be an evaluated or executed node
|
36
|
+
if nodes.first.is_a?(CommandNode)
|
37
37
|
time "Execute script" do
|
38
38
|
sql = [nodes.first.source]
|
39
39
|
end
|
data/lib/builder/node.rb
CHANGED
@@ -41,7 +41,7 @@ module Prick
|
|
41
41
|
@source_lines = nil
|
42
42
|
end
|
43
43
|
|
44
|
-
def to_s() [path, args].compact.join(" ") end
|
44
|
+
def to_s() @to_s ||= [path, args].compact.join(" ") end
|
45
45
|
def inspect() to_s end
|
46
46
|
def dump() puts "#{inspect} (#{schema})" end
|
47
47
|
|
@@ -121,41 +121,45 @@ module Prick
|
|
121
121
|
def self.objects() @@objects end
|
122
122
|
end
|
123
123
|
|
124
|
-
class
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
class CommandNode < Node
|
125
|
+
alias_method :command, :to_s
|
126
|
+
|
127
|
+
def filename = File.basename(path)
|
128
|
+
def relpath = path.sub(/^#{Dir.getwd}\//, "")
|
129
129
|
|
130
130
|
def initialize(parent, phase, path, args = nil)
|
131
|
+
constrain args, [String]
|
131
132
|
super(parent, phase, :exe, path, args)
|
132
|
-
@pipe = Command::Pipe.new(to_s, stderr: nil)
|
133
133
|
end
|
134
134
|
|
135
135
|
def inspect() "#{path} #{(args || []).join(" ")}" end
|
136
136
|
|
137
137
|
protected
|
138
|
-
def
|
138
|
+
def execute_command
|
139
139
|
begin
|
140
|
-
|
141
|
-
sql = pipe.wait
|
140
|
+
Command.command(Prick.state.bash_environment, command)
|
142
141
|
rescue Command::Error => ex
|
143
|
-
message = "
|
142
|
+
message = "Error executing '#{command}'\n" + ex.stderr.map { |l| " #{l}" }.join("\n")
|
144
143
|
raise Prick::Error.new(message)
|
145
|
-
|
146
|
-
rescue Errno::EPIPE
|
147
|
-
raise Prick::Error, "Pipe fail in #{path} called from #{parent.path}\n" +
|
148
|
-
"Tip: Read username/database from standard input"
|
149
|
-
end
|
150
|
-
if pipe.status != 0
|
151
|
-
$stderr.puts pipe.error
|
152
|
-
raise Prick::Error, "Failed executing #{path} called from #{parent.path}"
|
153
144
|
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class EvalNode < CommandNode
|
149
|
+
def read_source
|
150
|
+
sql = execute_command
|
154
151
|
@source_lines = 1 + 1 + sql.count("\n")
|
155
152
|
["set search_path to #{schema}, pg_temp;\n", sql]
|
156
153
|
end
|
157
154
|
end
|
158
155
|
|
156
|
+
class ExecNode < CommandNode
|
157
|
+
def read_source
|
158
|
+
execute_command
|
159
|
+
[]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
159
163
|
# A build.yml file node
|
160
164
|
class BuildNode < Node
|
161
165
|
def nodes() @nodes ||= init_nodes + decl_nodes + seed_nodes + term_nodes end
|
data/lib/builder/parser.rb
CHANGED
@@ -34,6 +34,91 @@ module Prick
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
# Search for an executable in path
|
38
|
+
def find_executable(filename) # ChatGPT
|
39
|
+
Prick.state.executable_search_path.split(File::PATH_SEPARATOR).each do |directory|
|
40
|
+
path = File.join(directory, filename)
|
41
|
+
return path if File.executable?(path)
|
42
|
+
end
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Expand $ENVIRONMENT variable in file names. The function implements a
|
47
|
+
# hierarchy of environments:
|
48
|
+
#
|
49
|
+
# production
|
50
|
+
# (online)
|
51
|
+
# development
|
52
|
+
# online
|
53
|
+
# offline
|
54
|
+
# backend
|
55
|
+
# frontend
|
56
|
+
# test
|
57
|
+
#
|
58
|
+
# If an environment doesn't exist in #dir, then the higher level
|
59
|
+
# environments are tried in turn. Eg. if the current environment is
|
60
|
+
# 'test', the algorithm expands '$ENVIRONMENT' to 'test', 'offline', and
|
61
|
+
# 'development' until an existing file is found. If no file is found the
|
62
|
+
# the unexpanded value is returned
|
63
|
+
#
|
64
|
+
# The production environment acts as a online environment but not a
|
65
|
+
# development environment. This means it will first search for
|
66
|
+
# 'production', then 'online', and then stop without searching for
|
67
|
+
# 'development'
|
68
|
+
#
|
69
|
+
# NOTE: This is a hardcoded feature for an internal project. It is
|
70
|
+
# configurable in the next major version
|
71
|
+
#
|
72
|
+
# TODO: Refactor: dir is not handled well when the filename includes a
|
73
|
+
# $PWD variblea
|
74
|
+
#
|
75
|
+
def expand_filename(dir, filename)
|
76
|
+
# Expand variables
|
77
|
+
path = expand_variables(filename, Prick.state.bash_environment)
|
78
|
+
|
79
|
+
# Use only filename as template if expansion is an absolute path
|
80
|
+
if path.start_with? "/"
|
81
|
+
template = filename
|
82
|
+
else
|
83
|
+
template = "#{dir}/#{filename}"
|
84
|
+
path = "#{dir}/#{path}"
|
85
|
+
end
|
86
|
+
return path if File.exist?(path)
|
87
|
+
|
88
|
+
# Iterate through environments
|
89
|
+
env = Prick.state.environment.to_s
|
90
|
+
while true
|
91
|
+
return path if File.exist?(path)
|
92
|
+
case env
|
93
|
+
when "production"
|
94
|
+
file = expand_variables(path, ENVIRONMENT: "online") or return nil
|
95
|
+
return file if File.exist? file
|
96
|
+
break
|
97
|
+
when "development"; break
|
98
|
+
when "online"; env = "development"
|
99
|
+
when "offline"; env = "development"
|
100
|
+
when "backend"; env = "offline"
|
101
|
+
when "frontend"; env = "offline"
|
102
|
+
when "test"; env = "offline"
|
103
|
+
else
|
104
|
+
raise Error, "Illegal env: '#{env}'"
|
105
|
+
end
|
106
|
+
path = expand_variables(template, Prick.state.bash_environment.merge(ENVIRONMENT: env))
|
107
|
+
end
|
108
|
+
|
109
|
+
# Look for executable in PATH
|
110
|
+
if filename !~ /\// && (path = find_executable(filename))
|
111
|
+
return path
|
112
|
+
else
|
113
|
+
return nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Expand $ENVIRONMENT variable
|
118
|
+
def expand_string(string)
|
119
|
+
expand_variables(string, ENVIRONMENT: Prick.state.environment.to_s, PWD: Dir.getwd)
|
120
|
+
end
|
121
|
+
|
37
122
|
def parse_directory(parent, dir)
|
38
123
|
build_file = "#{dir}/build.yml".sub(/\/\//, "/")
|
39
124
|
if File.exist? build_file
|
@@ -77,89 +162,24 @@ module Prick
|
|
77
162
|
unit
|
78
163
|
end
|
79
164
|
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
# production
|
84
|
-
# (online)
|
85
|
-
# development
|
86
|
-
# online
|
87
|
-
# offline
|
88
|
-
# backend
|
89
|
-
# frontend
|
90
|
-
# test
|
91
|
-
#
|
92
|
-
# If an environment doesn't exist in #dir, then the higher level
|
93
|
-
# environments are tried in turn. Eg. if the current environment is
|
94
|
-
# 'test', the algorithm expands '$ENVIRONMENT' to 'test', 'offline', and
|
95
|
-
# 'development' until an existing file is found. If no file is found the
|
96
|
-
# the unexpanded value is returned
|
97
|
-
#
|
98
|
-
# NOTE: This is a hardcoded feature for an internal project. It is
|
99
|
-
# configurable in the next major version
|
100
|
-
#
|
101
|
-
def expand_filename(dir, filename)
|
102
|
-
if File.exist?("#{dir}/#{filename}")
|
103
|
-
return filename
|
104
|
-
elsif filename =~ /\$ENVIRONMENT|\$\{ENVIRONMENT\}/
|
105
|
-
env = Prick.state.environment.to_s
|
106
|
-
while true
|
107
|
-
file = expand_variables(filename, ENVIRONMENT: env, PWD: Dir.getwd)
|
108
|
-
return file if File.exist? "#{dir}/#{file}"
|
109
|
-
case env
|
110
|
-
when "production"
|
111
|
-
file = expand_variables(filename, ENVIRONMENT: "online", PWD: Dir.getwd) or return nil
|
112
|
-
return file if File.exist? "#{dir}/#{file}"
|
113
|
-
return nil
|
114
|
-
when "development"; return nil
|
115
|
-
when "online"; env = "development"
|
116
|
-
when "offline"; env = "development"
|
117
|
-
when "backend"; env = "offline"
|
118
|
-
when "frontend"; env = "offline"
|
119
|
-
when "test"; env = "offline"
|
120
|
-
else
|
121
|
-
raise Error, "Illegal env: '#{env}'"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
else
|
125
|
-
return nil
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
# Expand $ENVIRONMENT variable
|
130
|
-
def expand_string(string)
|
131
|
-
expand_variables(string, ENVIRONMENT: Prick.state.environment.to_s, PWD: Dir.getwd)
|
132
|
-
end
|
133
|
-
|
165
|
+
# Returns path, filename, and an array of arguments. It is an error if
|
166
|
+
# the file can't be found unless #optional is true. In that case a nil
|
167
|
+
# value is returned
|
134
168
|
def parse_file_entry(unit, dir, entry)
|
135
169
|
entry = entry.sub(/\/$/, "")
|
136
170
|
if entry =~ /^(\S+?)(\?)?(?:\s+(.+))?\s*$/
|
137
|
-
|
171
|
+
command = $1
|
138
172
|
optional = !$2.nil?
|
139
173
|
args = expand_string($3 || '').split
|
140
|
-
|
141
|
-
|
142
|
-
!
|
174
|
+
path = expand_filename(dir, command)
|
175
|
+
path || optional or raise Error, "Can't find '#{entry}' in #{dir}/ from #{unit}"
|
176
|
+
!path.nil? or return nil
|
143
177
|
else
|
144
178
|
raise Error, "Not a file name: '#{entry}'"
|
145
179
|
end
|
146
|
-
path
|
147
|
-
[path, entry, file, args].flatten
|
180
|
+
[path, Array(args).flatten]
|
148
181
|
end
|
149
182
|
|
150
|
-
# def parse_file_entry(dir, entry)
|
151
|
-
# name = expand_environment(dir, entry)
|
152
|
-
# name.sub!(/\/$/, "")
|
153
|
-
# if name =~ /^(\S+)\s+(.+)$/ # has arguments -> exe
|
154
|
-
# file = $1
|
155
|
-
# args = $2.split
|
156
|
-
# else
|
157
|
-
# file = name
|
158
|
-
# end
|
159
|
-
# path = "#{dir}/#{file}"
|
160
|
-
# [path, name, file, args]
|
161
|
-
# end
|
162
|
-
|
163
183
|
def parse_entry(unit, phase, dir, entry)
|
164
184
|
if entry.is_a?(Hash)
|
165
185
|
entry.size == 1 or raise Error, "sql and module are single-line values"
|
@@ -168,19 +188,27 @@ module Prick
|
|
168
188
|
when "sql"
|
169
189
|
InlineNode.new(unit, phase, unit.path, expand_string(value))
|
170
190
|
when "call"
|
171
|
-
(path,
|
191
|
+
(path, args = parse_file_entry(unit, dir, value)) or return nil
|
192
|
+
args.size >= 2 or raise Error, "Illegal number of arguments"
|
193
|
+
klass = args.shift
|
194
|
+
command = args.shift
|
172
195
|
klass && command or raise "Illegal number of arguments: #{value}"
|
173
|
-
ModuleNode.new(unit, phase,
|
196
|
+
ModuleNode.new(unit, phase, path, klass, command, args)
|
197
|
+
when "eval"
|
198
|
+
(path, args = parse_file_entry(unit, dir, value)) or return nil
|
199
|
+
EvalNode.new(unit, phase, path, args)
|
174
200
|
when "exec"
|
175
|
-
(path,
|
176
|
-
|
201
|
+
(path, args = parse_file_entry(unit, dir, value)) or return nil
|
202
|
+
ExecNode.new(unit, phase, path, args)
|
177
203
|
else
|
178
204
|
raise Error, "Illegal key: #{key}"
|
179
205
|
end
|
180
206
|
else
|
181
|
-
(path,
|
207
|
+
(path, args = parse_file_entry(unit, dir, entry)) or return nil
|
182
208
|
if File.directory? path
|
183
209
|
parse_directory(unit, path)
|
210
|
+
elsif File.executable? path
|
211
|
+
ExecNode.new(unit, phase, path, args)
|
184
212
|
elsif File.file? path
|
185
213
|
case path
|
186
214
|
when /\.sql$/
|
@@ -188,14 +216,11 @@ module Prick
|
|
188
216
|
when /\.fox$/
|
189
217
|
FoxNode.new(unit, :seed, path)
|
190
218
|
else
|
191
|
-
|
192
|
-
ExeNode.new(unit, phase, path, args)
|
193
|
-
else
|
194
|
-
raise Error, "Unrecognized file type #{File.basename(path)} in #{dir}"
|
195
|
-
end
|
219
|
+
raise Error, "Expected executable, fox, or sql file: #{File.basename(path)} in #{dir}"
|
196
220
|
end
|
197
221
|
else
|
198
|
-
|
222
|
+
path =
|
223
|
+
raise Error, "Can't find '#{entry}' in #{dir}/ from #{unit}"
|
199
224
|
end
|
200
225
|
end
|
201
226
|
end
|
data/lib/local/command.rb
CHANGED
@@ -97,16 +97,15 @@ module Command
|
|
97
97
|
# command on standard-input, if it is a IO object that IO object is piped to
|
98
98
|
# the command
|
99
99
|
#
|
100
|
-
# By default #command pass through
|
101
|
-
#
|
102
|
-
#
|
103
|
-
# "2>/dev/null" to the command
|
100
|
+
# By default #command pass through stderr but if :stderr is true, #command
|
101
|
+
# will instead return a tuple of stdout/stderr lines. If :stderr is false,
|
102
|
+
# stderr is ignored and is the same as adding "2>/dev/null" to the command
|
104
103
|
#
|
105
|
-
# #command raises a Command::Error exception if the command
|
106
|
-
#
|
104
|
+
# #command raises a Command::Error exception if the command returns with an exit
|
105
|
+
# code != 0 unless :fail is false. In that case the the exit code can be
|
107
106
|
# fetched from Command::status
|
108
107
|
#
|
109
|
-
def command(cmd, stdin: nil, stderr: nil, fail: true)
|
108
|
+
def command(env = {}, cmd, stdin: nil, stderr: nil, fail: true)
|
110
109
|
cmd = "set -o errexit\nset -o pipefail\n#{cmd}"
|
111
110
|
|
112
111
|
pw = IO::pipe # pipe[0] for read, pipe[1] for write
|
@@ -129,7 +128,8 @@ module Command
|
|
129
128
|
STDERR.reopen(pe[1])
|
130
129
|
pe[1].close
|
131
130
|
|
132
|
-
|
131
|
+
env
|
132
|
+
exec(env.map { |k,v| [k.to_s, v.to_s] }.to_h, cmd)
|
133
133
|
}
|
134
134
|
|
135
135
|
pw[0].close
|
@@ -143,15 +143,14 @@ module Command
|
|
143
143
|
when Array; pw[1].write(stdin.join("\n") + "\n")
|
144
144
|
end
|
145
145
|
pw[1].flush
|
146
|
-
pw[1].close
|
147
146
|
end
|
147
|
+
pw[1].close # Closing standard input so the command doesn't hang on read
|
148
148
|
|
149
149
|
@status = Process.waitpid2(pid)[1].exitstatus
|
150
150
|
|
151
151
|
out = pr[0].readlines.map(&:chomp)
|
152
152
|
err = pe[0].readlines.map(&:chomp)
|
153
153
|
|
154
|
-
pw[1].close if !stdin
|
155
154
|
pr[0].close
|
156
155
|
pe[0].close
|
157
156
|
|
@@ -171,13 +170,6 @@ module Command
|
|
171
170
|
end
|
172
171
|
end
|
173
172
|
|
174
|
-
# Exit status of the last command. FIXME: This is not usable because the
|
175
|
-
# methods raise an exception if the command exited with anything but 0
|
176
|
-
def status() @status end
|
177
|
-
|
178
|
-
# Stored exception when #command is called with :fail true
|
179
|
-
def exception() @exception end
|
180
|
-
|
181
173
|
# Like command but returns true if the command exited with the expected
|
182
174
|
# status. Note that it suppresses standard-error by default
|
183
175
|
#
|
@@ -186,6 +178,12 @@ module Command
|
|
186
178
|
@status == expect
|
187
179
|
end
|
188
180
|
|
181
|
+
# Exit status of the last command
|
182
|
+
def status() @status end
|
183
|
+
|
184
|
+
# Exception of the last command if it failed, otherwise nil TODO What is this used for?
|
185
|
+
def exception() @exception end
|
186
|
+
|
189
187
|
module_function :command
|
190
188
|
module_function :status
|
191
189
|
module_function :exception
|
data/lib/prick/constants.rb
CHANGED
@@ -14,8 +14,10 @@ module Prick
|
|
14
14
|
DIRS = [
|
15
15
|
MIGRATION_DIR = "migration",
|
16
16
|
SCHEMA_DIR = "schema",
|
17
|
-
|
17
|
+
SCHEMA_PRICK_DIR = "#{SCHEMA_DIR}/prick",
|
18
18
|
PUBLIC_DIR = "#{SCHEMA_DIR}/public",
|
19
|
+
BIN_DIR = "bin",
|
20
|
+
LIBEXEC_DIR = "libexec",
|
19
21
|
VAR_DIR = "var",
|
20
22
|
CACHE_DIR = "#{VAR_DIR}/cache",
|
21
23
|
SPOOL_DIR = "#{VAR_DIR}/spool",
|
@@ -24,6 +26,12 @@ module Prick
|
|
24
26
|
SPEC_DIR = "spec"
|
25
27
|
]
|
26
28
|
|
29
|
+
# Prick project root directory
|
30
|
+
PRICK_DIR = Dir.getwd
|
31
|
+
|
32
|
+
# Search path for executables
|
33
|
+
PRICK_PATH = "#{ENV['PATH']}:#{PRICK_DIR}/#{BIN_DIR}:#{PRICK_DIR}/#{LIBEXEC_DIR}"
|
34
|
+
|
27
35
|
# Project specification file
|
28
36
|
PRICK_PROJECT_FILE = "prick.yml"
|
29
37
|
PRICK_PROJECT_PATH = PRICK_PROJECT_FILE
|
@@ -42,7 +50,7 @@ module Prick
|
|
42
50
|
|
43
51
|
# Schema data file
|
44
52
|
SCHEMA_VERSION_FILE = "data.sql"
|
45
|
-
SCHEMA_VERSION_PATH = File.join(
|
53
|
+
SCHEMA_VERSION_PATH = File.join(SCHEMA_PRICK_DIR, SCHEMA_VERSION_FILE)
|
46
54
|
|
47
55
|
# Rspec temporary directory
|
48
56
|
SPEC_TMP_DIR = "spec"
|
data/lib/prick/state.rb
CHANGED
@@ -36,6 +36,35 @@ module Prick
|
|
36
36
|
# Name of database user
|
37
37
|
attr_accessor :username
|
38
38
|
|
39
|
+
# Prick project dir. This is not a constant because exe/prick can change directory
|
40
|
+
def prick_dir
|
41
|
+
@prick_dir ||= Dir.getwd
|
42
|
+
end
|
43
|
+
|
44
|
+
# Prick executable search_path
|
45
|
+
def executable_search_path
|
46
|
+
@executable_search_path ||= "#{ENV['PATH']}:#{prick_dir}/#{BIN_DIR}:#{prick_dir}/#{LIBEXEC_DIR}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def bash_environment
|
50
|
+
ENV.to_h.merge({
|
51
|
+
DATABASE: Prick.state.database,
|
52
|
+
USERNAME: Prick.state.username,
|
53
|
+
ENVIRONMENT: Prick.state.environment.to_s,
|
54
|
+
PRICK_DIR: Prick.state.prick_dir,
|
55
|
+
PRICK_SCHEMADIR: File.join(Prick.state.prick_dir, SCHEMA_DIR),
|
56
|
+
PRICK_BINDIR: File.join(Prick.state.prick_dir, BIN_DIR),
|
57
|
+
PRICK_LIBEXECDIR: File.join(Prick.state.prick_dir, LIBEXEC_DIR),
|
58
|
+
PRICK_VARDIR: File.join(Prick.state.prick_dir, VAR_DIR),
|
59
|
+
PRICK_CACHEDIR: File.join(Prick.state.prick_dir, CACHE_DIR),
|
60
|
+
PRICK_SPOOLDIR: File.join(Prick.state.prick_dir, SPOOL_DIR),
|
61
|
+
PRICK_TMPDIR: File.join(Prick.state.prick_dir, TMP_DIR),
|
62
|
+
PRICK_CLONEDIR: File.join(Prick.state.prick_dir, CLONE_DIR),
|
63
|
+
PRICK_SPECDIR: File.join(Prick.state.prick_dir, BIN_DIR),
|
64
|
+
PATH: Prick.state.executable_search_path
|
65
|
+
})
|
66
|
+
end
|
67
|
+
|
39
68
|
def self.load
|
40
69
|
begin
|
41
70
|
h = YAML.load(File.read PRICK_PROJECT_PATH)
|
data/lib/prick/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.28.
|
4
|
+
version: 0.28.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claus Rasmussen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: semantic
|
@@ -231,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
231
231
|
- !ruby/object:Gem::Version
|
232
232
|
version: '0'
|
233
233
|
requirements: []
|
234
|
-
rubygems_version: 3.3.
|
234
|
+
rubygems_version: 3.3.18
|
235
235
|
signing_key:
|
236
236
|
specification_version: 4
|
237
237
|
summary: A release control and management system for postgresql
|