prick 0.18.0 → 0.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +10 -4
  3. data/README.md +7 -7
  4. data/Rakefile +3 -1
  5. data/TODO +13 -11
  6. data/bin/console +2 -1
  7. data/doc/build-yml.txt +14 -0
  8. data/exe/prick +264 -28
  9. data/lib/builder/batch.rb +147 -0
  10. data/lib/builder/builder.rb +122 -0
  11. data/lib/builder/node.rb +189 -0
  12. data/lib/builder/node_pool.rb +105 -0
  13. data/lib/builder/parser.rb +120 -0
  14. data/lib/local/command.rb +193 -0
  15. data/lib/{prick → local}/git.rb +148 -22
  16. data/lib/local/timer.rb +98 -0
  17. data/lib/prick/constants.rb +54 -66
  18. data/lib/prick/diff.rb +28 -18
  19. data/lib/prick/prick_version.rb +161 -0
  20. data/lib/prick/state.rb +80 -165
  21. data/lib/prick/version.rb +2 -163
  22. data/lib/prick.rb +43 -27
  23. data/lib/share/init/.gitignore +10 -0
  24. data/lib/share/init/.prick-context +2 -0
  25. data/lib/share/init/.rspec +3 -0
  26. data/{share/schema/schema/public → lib/share/init/migration}/.keep +0 -0
  27. data/lib/share/init/prick.yml +6 -0
  28. data/lib/share/init/schema/.keep +0 -0
  29. data/lib/share/init/schema/build.yml +2 -0
  30. data/lib/share/init/schema/prick/.keep +0 -0
  31. data/lib/share/init/schema/prick/build.yml +5 -0
  32. data/lib/share/init/schema/prick/data.sql +6 -0
  33. data/{share/schema → lib/share/init}/schema/prick/tables.sql +2 -3
  34. data/lib/share/init/schema/public/.keep +0 -0
  35. data/lib/share/init/spec/prick_helper.rb +1 -0
  36. data/lib/share/init/spec/prick_spec.rb +6 -0
  37. data/lib/share/init/spec/spec_helper.rb +50 -0
  38. data/lib/share/migrate/migration/build.yml +4 -0
  39. data/lib/share/migrate/migration/diff.after-tables.sql +0 -0
  40. data/lib/share/migrate/migration/diff.before-tables.sql +0 -0
  41. data/lib/share/migrate/migration/diff.tables.sql +0 -0
  42. data/lib/subcommand/prick-build.rb +55 -0
  43. data/lib/subcommand/prick-create.rb +78 -0
  44. data/lib/subcommand/prick-drop.rb +25 -0
  45. data/lib/subcommand/prick-fox.rb +62 -0
  46. data/lib/subcommand/prick-init.rb +46 -0
  47. data/lib/subcommand/prick-make.rb +202 -0
  48. data/lib/subcommand/prick-migrate.rb +37 -0
  49. data/lib/subcommand/prick-release.rb +23 -0
  50. data/lib/subcommand/prick-setup.rb +20 -0
  51. data/lib/subcommand/prick-teardown.rb +18 -0
  52. data/prick.gemspec +43 -16
  53. metadata +161 -72
  54. data/.gitignore +0 -29
  55. data/.travis.yml +0 -7
  56. data/doc/create_release.txt +0 -17
  57. data/doc/flow.txt +0 -98
  58. data/doc/migra +0 -1
  59. data/doc/migrations.txt +0 -172
  60. data/doc/notes.txt +0 -116
  61. data/doc/prick.txt +0 -114
  62. data/doc/sh.prick +0 -316
  63. data/lib/ext/algorithm.rb +0 -14
  64. data/lib/ext/fileutils.rb +0 -26
  65. data/lib/ext/forward_method.rb +0 -18
  66. data/lib/ext/pg.rb +0 -18
  67. data/lib/ext/shortest_path.rb +0 -44
  68. data/lib/prick/archive.rb +0 -124
  69. data/lib/prick/branch.rb +0 -254
  70. data/lib/prick/builder.rb +0 -205
  71. data/lib/prick/cache.rb +0 -34
  72. data/lib/prick/command.rb +0 -102
  73. data/lib/prick/database.rb +0 -82
  74. data/lib/prick/dsort.rb +0 -151
  75. data/lib/prick/ensure.rb +0 -119
  76. data/lib/prick/exceptions.rb +0 -25
  77. data/lib/prick/head.rb +0 -183
  78. data/lib/prick/migration.rb +0 -70
  79. data/lib/prick/program.rb +0 -506
  80. data/lib/prick/project.rb +0 -626
  81. data/lib/prick/rdbms.rb +0 -137
  82. data/lib/prick/schema.rb +0 -27
  83. data/lib/prick/share.rb +0 -64
  84. data/libexec/strip-comments +0 -33
  85. data/make_releases +0 -72
  86. data/make_schema +0 -10
  87. data/share/diff/diff.after-tables.sql +0 -4
  88. data/share/diff/diff.before-tables.sql +0 -4
  89. data/share/diff/diff.tables.sql +0 -8
  90. data/share/features/diff.sql +0 -2
  91. data/share/features/feature/diff.sql +0 -2
  92. data/share/features/feature/migrate.sql +0 -2
  93. data/share/features/features.sql +0 -2
  94. data/share/features/features.yml +0 -2
  95. data/share/features/migrations.sql +0 -4
  96. data/share/gitignore +0 -2
  97. data/share/migration/diff.tables.sql +0 -8
  98. data/share/migration/features.yml +0 -6
  99. data/share/migration/migrate.sql +0 -3
  100. data/share/migration/migrate.yml +0 -8
  101. data/share/migration/tables.sql +0 -3
  102. data/share/schema/build.yml +0 -14
  103. data/share/schema/schema/build.yml +0 -3
  104. data/share/schema/schema/prick/build.yml +0 -14
  105. data/share/schema/schema/prick/data.sql +0 -7
  106. data/share/schema/schema/prick/schema.sql +0 -3
  107. data/share/schema/schema/public/build.yml +0 -13
  108. data/share/schema/schema.sql +0 -3
  109. data/test_assorted +0 -192
  110. data/test_feature +0 -112
  111. data/test_refactor +0 -34
  112. data/test_single_dev +0 -83
data/doc/sh.prick DELETED
@@ -1,316 +0,0 @@
1
- #!/usr/bin/bash
2
-
3
- # Name
4
- # prick - Database project tool
5
- #
6
- # Usage
7
- # prick prepare|migrate|release
8
- #
9
- # Commands
10
- # prepare NEW-RELEASE
11
- # Stamps NEW-RELEASE into the database
12
- # migrate [OLD-RELEASE]
13
- # Create a migration from OLD-RELEASE to the prepared release.
14
- # OLD-RELEASE defaults to the last registered release
15
- # release
16
- # Release the prepared release
17
- #
18
- # Files
19
- # prick use the following sub-directories:
20
- #
21
- # releases/
22
- # <database>-<release>.dump.gz
23
- # ...
24
- # migrations/
25
- # migrate-<from>-<to>[.sql]
26
- # ...
27
- #
28
- # The releases directory contains schema backups that makes it easy to
29
- # restore a earlier release used to generated migrations. The migrations directory
30
- # contains migrations from one release to another. 'prick migrate' generates
31
- # a SQL migration file but you can replace it with an executable if needed
32
- #
33
-
34
- # TODO: Schema-only dump of database
35
- # pg_dump --no-owner --no-privileges --schema-only name_of_database -f schema.dump.sql
36
-
37
-
38
- set -e
39
-
40
- . bash.include
41
-
42
- USAGE="prepare NEW-RELEASE
43
- migrate OLD-RELEASE
44
- release"
45
-
46
- DB=mikras
47
-
48
- function inoa() {
49
- error "Illegal number of arguments"
50
- }
51
-
52
- [ $# -ge 1 ] || inoa
53
- CMD=$1
54
- shift
55
-
56
- trap 'eval rm -rf $ERRFILE $TMPFILE $TMPDIR' EXIT
57
- ERRFILE=$(mktemp --tmpdir $PROGRAM.XXXXXXXXXX)
58
- TMPFILE=$(mktemp --tmpdir $PROGRAM.XXXXXXXXXX)
59
- TMPDIR=$(mktemp --tmpdir --directory $PROGRAM.XXXXXXXXXX)
60
- #echo $TMPFILE
61
- #echo $TMPDIR
62
-
63
- function last_release() {
64
- local path=$(ls releases/$DB-*.*.*.dump.gz 2>/dev/null | tail -1)
65
- local release=$(echo $path | sed -e "s/releases\/$DB-//" -e 's/\.dump\.gz$//')
66
- echo ${release:-0.0.0}
67
- }
68
-
69
- function current_release() {
70
- psql -qtAX -d $DB -c "select major || '.' || minor || '.' || patch from meta.versions"
71
- }
72
-
73
- function set_current_release() {
74
- set -- $(echo $1 | sed 's/\./ /g')
75
- local major=$1
76
- local minor=$2
77
- local patch=$3
78
-
79
- psql -qtAX -d $DB -c "update meta.versions set major = $major, minor = $minor, patch = $patch"
80
- }
81
-
82
- function has_release() {
83
- local release=$1
84
- local db=$DB-$release
85
- psql -qtAX -d $DB -l | grep -q "^$db|" &>/dev/null
86
- }
87
-
88
- function database_load() {
89
- local release=$1
90
- local db=$DB-$release
91
- local dump=releases/$db.dump.gz
92
- [ -f $dump ] || error "Can't find release dump $dump"
93
- [ ! has_release ] || error "Release $release is already loaded"
94
- createdb $db
95
- gzip --to-stdout $dump | psql -d $db
96
- }
97
-
98
- function redatabase_load() {
99
- local release=$1
100
- local db=$DB-$release
101
- local dump=releases/$db.dump.gz
102
- [ -f $dump ] || error "Can't find release dump $dump"
103
- [ ! has_release ] || dropdb $db
104
- createdb $db
105
- gzip --to-stdout $dump | psql -d $db
106
- }
107
-
108
-
109
- function prepare() {
110
- local new_release=$1
111
- mesg "Preparing $new_release"
112
-
113
- [ ! -f $new_release ] || error "New release already exists: $new_release_dump"
114
- set_current_release $new_release
115
- }
116
-
117
- function migrate() {
118
- local old_release=$1
119
- local new_release=$(current_release)
120
- local old_release_dump=releases/$DB-$old_release.dump.gz
121
- local new_release_dump=releases/$DB-$new_release_dump.gz
122
- local migration=migrations/migrate-$old_release-$new_release.sql
123
-
124
- mesg "Migrating $old_release to $new_release"
125
-
126
- [ -f $old_release_dump ] || error "Can't find old release: $old_release_dump"
127
- [ ! -f $new_release_dump ] || error "New release already exists: $new_release_dump"
128
- [ "$old_release" != "$new_release" ] ||
129
- error "Can't migrate $old_release to itself (did you forget to prepare the release?)"
130
- [ ! -f $migration ] || error "Won't overwrite migration $migration"
131
-
132
- has_release $old_release || database_load $old_release
133
- # migra --unsafe postgresql:///$DB-$old_release postgresql:///$DB || true #>$migration
134
- migra --unsafe postgresql:///$DB-$old_release postgresql:///$DB >$migration || {
135
- case $? in
136
- 0)
137
- mesg "No changes"
138
- ;;
139
- 2)
140
- mesg "Generated $migration"
141
- ;;
142
- *)
143
- rm -f $migration
144
- fail "migra failed"
145
- ;;
146
- esac
147
- }
148
- }
149
-
150
- function database() {
151
- local release=$1
152
- echo "$DB-$release"
153
- }
154
-
155
- function dumpfile() {
156
- local release=$1
157
- echo "releases/$DB-$release.dump.gz"
158
- }
159
-
160
- ###
161
- ### R E L E A S E
162
- ###
163
-
164
- function release_default() {
165
- psql -qtAX -d $DB -c "select major || '.' || minor || '.' || patch from meta.versions"
166
- }
167
-
168
- function release_exist() {
169
- local release=$1
170
- local dump=$(dumpfile $release)
171
- [ -f $dump ]
172
- }
173
-
174
- ###
175
- ### M I G R A T I O N S
176
- ###
177
-
178
- function migration_create() {
179
- local old_release=$1
180
- local new_release=$(release_default)
181
- }
182
-
183
- function migration_apply() {
184
- echo niy
185
- }
186
-
187
-
188
- ###
189
- ### D A T A B A S E
190
- ###
191
-
192
- function database_loaded() {
193
- local release=$1
194
- local db=$(database $release)
195
- psql -qtAX -d $DB -l | grep -q "^$db|" &>/dev/null
196
- }
197
-
198
- function database_build() {
199
- local release=$1
200
- local db=$(database $release)
201
- ! database_loaded $release || fail "Database $db is already loaded"
202
- mesg "Checking out release $release"
203
- git archive --format=tar $release >$TMPFILE
204
- (
205
- cd $TMPDIR
206
- tar xf $TMPFILE
207
-
208
- # No git access so set spec.files to []
209
- sed -i -e '/^ *spec.files/,+2d' mikras_db.gemspec -e 's/spec.files/[]/' mikras_db.gemspec
210
-
211
- mesg "Running bundle"
212
- bundle &>$ERRFILE || {
213
- cat $ERRFILE >&2
214
- fail "bundle failed"
215
- }
216
-
217
- # Set databse name
218
- sed -i "s/^DB=.*/DB=$(database $release)/" exe/build
219
-
220
- # Quote variables properly
221
- perl -pi -e 's/:(\w+)/:"\1"/g' schemas/db.sql
222
-
223
- # Replace schemas/skuffejern/users.sql - it is not possible to drop users because we
224
- # run several versions of the database
225
- for file in $(ls schemas/*/users.sql 2>/dev/null); do
226
- {
227
- psql -qtAX -d template1 \
228
- -c "select 1 from pg_user where pg_user.usename = 'anonymous'" \
229
- | grep -q 1 || psql -qtAX -d template1 -c "create user anonymous"
230
-
231
- psql -qtAX -d template1 \
232
- -c "select 1 from pg_roles where pg_roles.rolname = 'skuffejern_access'" \
233
- | grep -q 1 || psql -qtAX -d template1 -c "create role skuffejern_access"
234
- } >$file
235
- done
236
-
237
- mesg "Running rebuild"
238
- ./rebuild &>$ERRFILE || {
239
- cat $ERRFILE >&2
240
- fail "rebuild failed"
241
- }
242
- )
243
- }
244
-
245
- function database_save() {
246
- local release=$1
247
- local db=$(database $release)
248
- local dump=releases/$db.dump.gz
249
- [ ! -f $dump ] || fail "Won't overwrite release file $dump"
250
- # pg_dump --no-owner --no-privileges --schema-only name_of_database -f schema.dump.sql
251
- pg_dump --no-owner --schema-only $db | gzip --to-stdout >$dump
252
- }
253
-
254
- function database_load() {
255
- local release=$1
256
- local db=$(database $release)
257
- local dump=releases/$db.dump.gz
258
- ! database_loaded $db || fail "Database $db is already loaded"
259
- [ -f $dump ] || fail "Can't find release file $dump"
260
- createdb $db
261
- gunzip --to-stdout $dump | psql -d $db &>$ERRFILE || {
262
- cat $ERRFILE
263
- fail "psql failed"
264
- }
265
- }
266
-
267
- function database_drop() {
268
- local release=$1
269
- local db=$(database $release)
270
- dropdb $db
271
- }
272
-
273
-
274
- case $CMD in
275
- list)
276
- [ $# = 0 ] || inoa
277
- psql -qtAX -d template1 -l | sed -n "/mikras[-0-9.]*|/s/|.*//p"
278
- ;;
279
- build)
280
- [ $# = 1 ] || inoa
281
- database_build $1
282
- ;;
283
- save)
284
- [ $# = 1 ] || inoa
285
- database_save $1
286
- ;;
287
- load)
288
- [ $# = 1 ] || inoa
289
- database_load $1
290
- ;;
291
- reload)
292
- [ $# = 1 ] || inoa
293
- ! database_loaded $1 || database_drop $1
294
- database_load $1
295
- ;;
296
- drop)
297
- [ $# = 1 ] || inoa
298
- database_drop $1
299
- ;;
300
- prepare)
301
- [ $# = 1 ] || inoa
302
- prepare $1
303
- ;;
304
- migrate) # TODO: prick migrate from-release to-release
305
- [ $# -le 1 ] || inoa
306
- migrate ${1:-$(last_release)}
307
- ;;
308
- release)
309
- mesg "Releasing"
310
- ;;
311
- *)
312
- error "Illegal command: '$CMD'"
313
- ;;
314
- esac
315
-
316
-
data/lib/ext/algorithm.rb DELETED
@@ -1,14 +0,0 @@
1
-
2
- module Algorithm
3
- def follow(object, sym = nil, &block)
4
- sym.nil? == block_given? or raise "Can't use both symbol and block"
5
- a = []
6
- while object
7
- a << object
8
- object = block_given? ? yield(object) : object.send(sym)
9
- end
10
- a
11
- end
12
-
13
- module_function :follow
14
- end
data/lib/ext/fileutils.rb DELETED
@@ -1,26 +0,0 @@
1
-
2
-
3
- require 'pathname'
4
-
5
- module FileUtils
6
- def self.touch_p(file)
7
- dir = File.dirname(file)
8
- File.exist?(dir) or FileUtils.mkdir_p(dir)
9
- touch(file)
10
- file
11
- end
12
-
13
- def self.ln_sr(from, to)
14
- from = Pathname.new(from)
15
- to_dir = File.dirname(to)
16
- to_file = File.basename(to)
17
- relpath = from.relative_path_from(File.dirname(to))
18
- Dir.chdir(to_dir) { FileUtils.ln_s(relpath, File.basename(to)) }
19
- end
20
-
21
- def self.empty!(dir)
22
- Dir.chdir(dir) {
23
- FileUtils.rm_rf(Dir.children("."))
24
- }
25
- end
26
- end
@@ -1,18 +0,0 @@
1
-
2
- class Class
3
- # TODO: Check for arity
4
- def forward_methods(*methods, object)
5
- for method in Array(methods).flatten
6
- if method.to_s.end_with?("=")
7
- src = "def #{method}(args) raise if #{object}.nil?; #{object}.#{method}(args) end"
8
- else
9
- src = "def #{method}(*args) #{object}&.#{method}(*args) end"
10
- end
11
- class_eval(src)
12
- end
13
- end
14
-
15
- def forward_method(*args) forward_methods(*args) end
16
- end
17
-
18
-
data/lib/ext/pg.rb DELETED
@@ -1,18 +0,0 @@
1
- require 'pg'
2
-
3
- class PG::Result
4
- def value() self.getvalue(0, 0) end
5
-
6
- def each_value(&block)
7
- if block_given?
8
- self.each_row { |r| yield(r.first) }
9
- else
10
- self.each_row.map { |r| r.first }
11
- end
12
- end
13
-
14
- def empty?() ntuples == 0 end
15
-
16
- def to_a() self.values end
17
- end
18
-
@@ -1,44 +0,0 @@
1
-
2
- module Algorithm
3
- # Return (one of) the shortest path from `from` to `to` as a list of edges.
4
- # `edges` is a list of arrays with from-node and to-node as the first two
5
- # elements. Returns nil if no route was found
6
- #
7
- # The algorithm does slightly more work than it needs to because the same node
8
- # can be inserted more than once into the queue of nodes to be processed
9
- #
10
- def self.shortest_path(edges, from, to)
11
- pool = {} # Map from 'from' to map from 'to' to edge. Eg. pool[from][to] == edge-between-them
12
- edges.each { |edge| (pool[edge[0]] ||= {})[edge[1]] = edge }
13
-
14
- visited = {}
15
- prev = {}
16
-
17
- todo = [from]
18
- while true
19
- return nil if todo.empty?
20
-
21
- current = todo.shift
22
- break if current == to
23
-
24
- next if visited[current]
25
- visited[current] = true
26
-
27
- next if pool[current].nil?
28
- pool[current].each { |node, edge|
29
- prev[node] ||= edge
30
- todo << node
31
- }
32
- end
33
-
34
- to_node = to
35
- route = []
36
- while edge = prev[to_node]
37
- to_node = edge.first
38
- route.unshift edge
39
- break if from == to_node
40
- end
41
-
42
- route
43
- end
44
- end
data/lib/prick/archive.rb DELETED
@@ -1,124 +0,0 @@
1
-
2
- module Prick
3
- class DumpFile
4
- attr_reader :project
5
- attr_reader :name
6
- attr_reader :file
7
- attr_reader :path
8
-
9
- def initialize(project, name)
10
- @project = project
11
- @name = name
12
- @file = "#{project.name}-#{name}.#{DUMP_EXT}"
13
- @path = File.join(CACHE_DIR, @file)
14
- end
15
-
16
- def exist?() File.exist?(path) end
17
-
18
- def delete() FileUtils.rm_f(path) end
19
- end
20
- end
21
-
22
- __END__
23
-
24
-
25
-
26
- class Release
27
- attr_reader :project
28
- attr_reader :version
29
- attr_reader :semver
30
-
31
- # Associated Database object
32
- attr_reader :database
33
-
34
- # Name of release (eg. 'project-1.2.3')
35
- attr_reader :name
36
-
37
- # Release file (eb. 'project-1.2.3.dump.gz')
38
- attr_reader :file
39
-
40
- # Path to release file
41
- def path() File.join(RELEASE_DIR, file) end
42
-
43
- def initialize(project, version_or_semver, database: nil)
44
- @project = project
45
- @version, @semver = Semver::parse(version_or_semver)
46
- @name = "#{@project.name}-#{@semver}"
47
- @file = @name + RELEASE_DOT_EXT
48
- @database = database || Database.new(@name, @project.user)
49
- end
50
-
51
- def self.glob(project)
52
- "#{project.name}-*.#{RELEASE_EXT}"
53
- end
54
-
55
- # $1 matches the version
56
- def self.re(project)
57
- /^#{project.name}-(#{VERSION_RE.source})$/
58
- end
59
-
60
- # True if the release file exists
61
- def cached?() File.exist?(path) end
62
-
63
- def build() project.build(version) end
64
-
65
- def unbuild() FileUtils.rm_f(path) end
66
-
67
- # True if the database exists and is loaded
68
- def loaded?() database.loaded? end
69
-
70
- # Create database and load release
71
- def load(file = nil)
72
- file ||= path
73
- !loaded? or raise Error, "Release #{name} is already loaded"
74
- database.create
75
- database.load(file)
76
- end
77
-
78
- # Reload release
79
- def reload(file = path) unload; load(file) end
80
-
81
- # Delete a database. It is not an error if the database doesn't exists
82
- def unload() database.drop if loaded? end
83
-
84
- # Remove the release file
85
- def remove() FileUtils::rm_f(path) end
86
-
87
- # Compare two release by semantic version
88
- def <=>(other) self.semver <=> other.semver end
89
-
90
- # Render self a the name of the release (eg. 'project-1.2.3')
91
- def to_s() name end
92
-
93
- # Returns self so that you can do 'release = lookup(version).ensure(:loaded)'
94
- def ensure(state, expect: true)
95
- value = self.send(:"#{state}?")
96
- if value != expect
97
- state_methods = STATES[state] or raise Error, "Can't change state to #{state.inspect}"
98
- index = expect ? 0 : 1
99
- self.send(state_method[index])
100
- end
101
- self
102
- end
103
- end
104
-
105
- STATES = {
106
- cached: [:build, :unbuild],
107
- loaded: [:load, :unload]
108
- }
109
- end
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-