prick 0.17.0 → 0.20.1

Sign up to get free protection for your applications and to get access to all the features.
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 -202
  71. data/lib/prick/cache.rb +0 -34
  72. data/lib/prick/command.rb +0 -93
  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
-