prick 0.19.0 → 0.20.1
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.
- checksums.yaml +4 -4
- data/Gemfile +10 -4
- data/README.md +7 -7
- data/Rakefile +3 -1
- data/TODO +13 -11
- data/bin/console +2 -1
- data/doc/build-yml.txt +14 -0
- data/exe/prick +237 -19
- data/lib/builder/batch.rb +147 -0
- data/lib/builder/builder.rb +122 -0
- data/lib/builder/node.rb +189 -0
- data/lib/builder/node_pool.rb +105 -0
- data/lib/builder/parser.rb +120 -0
- data/lib/local/command.rb +193 -0
- data/lib/{prick → local}/git.rb +148 -22
- data/lib/local/timer.rb +98 -0
- data/lib/prick/constants.rb +54 -66
- data/lib/prick/diff.rb +28 -18
- data/lib/prick/prick_version.rb +161 -0
- data/lib/prick/state.rb +80 -165
- data/lib/prick/version.rb +2 -163
- data/lib/prick.rb +38 -24
- data/lib/share/init/.gitignore +10 -0
- data/lib/share/init/.prick-context +2 -0
- data/lib/share/init/.rspec +3 -0
- data/{share/schema/schema/public → lib/share/init/migration}/.keep +0 -0
- data/lib/share/init/prick.yml +6 -0
- data/lib/share/init/schema/.keep +0 -0
- data/lib/share/init/schema/build.yml +2 -0
- data/lib/share/init/schema/prick/.keep +0 -0
- data/lib/share/init/schema/prick/build.yml +5 -0
- data/lib/share/init/schema/prick/data.sql +6 -0
- data/{share/schema → lib/share/init}/schema/prick/tables.sql +2 -3
- data/lib/share/init/schema/public/.keep +0 -0
- data/lib/share/init/spec/prick_helper.rb +1 -0
- data/lib/share/init/spec/prick_spec.rb +6 -0
- data/lib/share/init/spec/spec_helper.rb +50 -0
- data/lib/share/migrate/migration/build.yml +4 -0
- data/lib/share/migrate/migration/diff.after-tables.sql +0 -0
- data/lib/share/migrate/migration/diff.before-tables.sql +0 -0
- data/lib/share/migrate/migration/diff.tables.sql +0 -0
- data/lib/subcommand/prick-build.rb +55 -0
- data/lib/subcommand/prick-create.rb +78 -0
- data/lib/subcommand/prick-drop.rb +25 -0
- data/lib/subcommand/prick-fox.rb +62 -0
- data/lib/subcommand/prick-init.rb +46 -0
- data/lib/subcommand/prick-make.rb +202 -0
- data/lib/subcommand/prick-migrate.rb +37 -0
- data/lib/subcommand/prick-release.rb +23 -0
- data/lib/subcommand/prick-setup.rb +20 -0
- data/lib/subcommand/prick-teardown.rb +18 -0
- data/prick.gemspec +32 -21
- metadata +95 -76
- data/.gitignore +0 -29
- data/.travis.yml +0 -7
- data/doc/create_release.txt +0 -17
- data/doc/flow.txt +0 -98
- data/doc/migra +0 -1
- data/doc/migrations.txt +0 -172
- data/doc/notes.txt +0 -116
- data/doc/prick.txt +0 -114
- data/doc/sh.prick +0 -316
- data/lib/ext/algorithm.rb +0 -14
- data/lib/ext/fileutils.rb +0 -26
- data/lib/ext/forward_method.rb +0 -18
- data/lib/ext/pg.rb +0 -18
- data/lib/ext/shortest_path.rb +0 -44
- data/lib/prick/archive.rb +0 -124
- data/lib/prick/branch.rb +0 -265
- data/lib/prick/builder.rb +0 -246
- data/lib/prick/cache.rb +0 -34
- data/lib/prick/command.rb +0 -104
- data/lib/prick/database.rb +0 -82
- data/lib/prick/dsort.rb +0 -151
- data/lib/prick/ensure.rb +0 -119
- data/lib/prick/exceptions.rb +0 -25
- data/lib/prick/head.rb +0 -189
- data/lib/prick/migration.rb +0 -70
- data/lib/prick/program.rb +0 -287
- data/lib/prick/project.rb +0 -626
- data/lib/prick/rdbms.rb +0 -137
- data/lib/prick/schema.rb +0 -27
- data/lib/prick/share.rb +0 -64
- data/libexec/strip-comments +0 -33
- data/make_releases +0 -72
- data/make_schema +0 -10
- data/share/diff/diff.after-tables.sql +0 -4
- data/share/diff/diff.before-tables.sql +0 -4
- data/share/diff/diff.tables.sql +0 -8
- data/share/features/diff.sql +0 -2
- data/share/features/feature/diff.sql +0 -2
- data/share/features/feature/migrate.sql +0 -2
- data/share/features/features.sql +0 -2
- data/share/features/features.yml +0 -2
- data/share/features/migrations.sql +0 -4
- data/share/gitignore +0 -2
- data/share/migration/diff.tables.sql +0 -8
- data/share/migration/features.yml +0 -6
- data/share/migration/migrate.sql +0 -3
- data/share/migration/migrate.yml +0 -8
- data/share/migration/tables.sql +0 -3
- data/share/schema/build.yml +0 -14
- data/share/schema/schema/build.yml +0 -3
- data/share/schema/schema/prick/build.yml +0 -14
- data/share/schema/schema/prick/data.sql +0 -7
- data/share/schema/schema/prick/schema.sql +0 -3
- data/share/schema/schema/public/build.yml +0 -13
- data/share/schema/schema.sql +0 -3
- data/test_assorted +0 -192
- data/test_feature +0 -112
- data/test_refactor +0 -34
- data/test_single_dev +0 -83
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'builder/builder.rb'
|
|
4
|
+
|
|
5
|
+
module Prick::SubCommand
|
|
6
|
+
def self.build(database, username, schema, builddir: "schema", timer: nil, dump: nil)
|
|
7
|
+
Timer.on! if timer
|
|
8
|
+
time "Prick::Command#build" do
|
|
9
|
+
begin
|
|
10
|
+
super_conn = PgConn.new
|
|
11
|
+
conn = nil
|
|
12
|
+
builder = nil
|
|
13
|
+
|
|
14
|
+
time "Load build object" do
|
|
15
|
+
if super_conn.rdbms.exist? database
|
|
16
|
+
conn = PgConn.new(database, username)
|
|
17
|
+
super_conn.rdbms.empty!(database)
|
|
18
|
+
else
|
|
19
|
+
super_conn.rdbms.create database, owner: username
|
|
20
|
+
conn = PgConn.new(database, username)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
builder = Prick::Build::Builder.new(conn, builddir)
|
|
24
|
+
builder.pool.delete_schema(builder.pool.after_schema(schema)) if schema
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
case dump
|
|
28
|
+
when :nodes; builder.nodes.reject { |node| node.is_a?(Build::BuildNode) }.map &:dump
|
|
29
|
+
when :allnodes; builder.nodes.map &:dump
|
|
30
|
+
when :batches; builder.dump
|
|
31
|
+
when nil;
|
|
32
|
+
else
|
|
33
|
+
raise Prick::Error, "Illegal dump type: #{dump.inspect}"
|
|
34
|
+
end && exit
|
|
35
|
+
|
|
36
|
+
time "Execute build object" do
|
|
37
|
+
builder.execute conn
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
rescue Prick::Error => ex
|
|
41
|
+
$stderr.puts ex.message
|
|
42
|
+
exit 1
|
|
43
|
+
|
|
44
|
+
rescue ::Command::Error => ex
|
|
45
|
+
$stderr.puts ex.message
|
|
46
|
+
exit 1
|
|
47
|
+
|
|
48
|
+
ensure
|
|
49
|
+
super_conn&.terminate
|
|
50
|
+
conn&.terminate
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
|
|
2
|
+
module Prick
|
|
3
|
+
module SubCommand
|
|
4
|
+
def self.create_migration(username, from_version, force: false, file: nil)
|
|
5
|
+
constrain from_version, PrickVersion
|
|
6
|
+
Git.clean? or raise "Won't migrate: Repository is dirty"
|
|
7
|
+
Git.synchronized? or raise "Won't migrate: Repository is not synchronized"
|
|
8
|
+
|
|
9
|
+
from_version != PrickVersion.zero or raise Prick::Error, "Can't migrate from release 0.0.0"
|
|
10
|
+
to_version = Prick.state.version
|
|
11
|
+
migration_dir = "#{MIGRATION_DIR}/#{from_version}"
|
|
12
|
+
migration_exist = File.directory? migration_dir
|
|
13
|
+
force || file || !migration_exist or raise Prick::Fail, "Migration #{from_version} exists"
|
|
14
|
+
|
|
15
|
+
$quiet = true if file
|
|
16
|
+
|
|
17
|
+
if file && migration_exist
|
|
18
|
+
File.open(file, "w") { |file|
|
|
19
|
+
for diff_file in DIFF_FILES
|
|
20
|
+
file.write File.read("#{migration_dir}/#{diff_file}")
|
|
21
|
+
end
|
|
22
|
+
}
|
|
23
|
+
else
|
|
24
|
+
from_version != to_version or raise Prick::Fail, "Can't migrate to same release"
|
|
25
|
+
from_version < to_version or raise Prick::Fail, "Can't migrate backwards (why not?)"
|
|
26
|
+
|
|
27
|
+
diff = nil
|
|
28
|
+
if force || !migration_exist
|
|
29
|
+
from_db = "#{Prick.state.name}-#{from_version}"
|
|
30
|
+
to_db = "#{Prick.state.name}-#{to_version}"
|
|
31
|
+
|
|
32
|
+
mesg "Migrating from #{from_version} to #{to_version}"
|
|
33
|
+
begin
|
|
34
|
+
origin = Git.origin
|
|
35
|
+
|
|
36
|
+
# Local repos are supported to ease testing
|
|
37
|
+
if File.directory?(origin)
|
|
38
|
+
origin = File.expand_path(origin)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
diff = Dir.mktmpdir { |tmpdir|
|
|
42
|
+
Dir.chdir(tmpdir) {
|
|
43
|
+
mesg " Building #{from_db}"
|
|
44
|
+
Git.clone(origin, from_version, branch: from_version)
|
|
45
|
+
Dir.chdir(from_version.to_s) { build(from_db, username, nil) }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
mesg " Building #{to_db}"
|
|
49
|
+
build(to_db, username, nil)
|
|
50
|
+
|
|
51
|
+
mesg " Creating diff"
|
|
52
|
+
Diff.new(from_db, to_db)
|
|
53
|
+
}
|
|
54
|
+
!diff.same? or raise Prick::Fail, "No changes"
|
|
55
|
+
ensure
|
|
56
|
+
drop_all(from_db)
|
|
57
|
+
drop_all(to_db)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
diff.write(file) if file
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
if file
|
|
65
|
+
File.open(file, "a") { |f|
|
|
66
|
+
f.puts "-- UPDATE VERSION"
|
|
67
|
+
f.puts File.readlines(SCHEMA_VERSION_PATH).grep_v(/^--/)
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
FileUtils.rm_rf migration_dir if force
|
|
71
|
+
FileUtils.mkdir_p migration_dir
|
|
72
|
+
Command.command "cp -a #{SHARE_PATH}/migrate/migration/. #{migration_dir}"
|
|
73
|
+
Dir.chdir(migration_dir) { diff.write(*DIFF_FILES, mark: true) }
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'builder/builder.rb'
|
|
4
|
+
|
|
5
|
+
module Prick::SubCommand
|
|
6
|
+
def self.drop_users(database)
|
|
7
|
+
PgConn.new(database) { |conn|
|
|
8
|
+
users = conn.role.list(database: database)
|
|
9
|
+
conn.role.drop(users, cascade: true)
|
|
10
|
+
}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.drop_database(database)
|
|
14
|
+
PgConn.new { |conn| conn.rdbms.drop database }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.drop_all(database)
|
|
18
|
+
PgConn.new { |conn|
|
|
19
|
+
users = conn.role.list(database: database)
|
|
20
|
+
PgConn.new(database) { |db| db.role.drop(users, cascade: true) }
|
|
21
|
+
conn.rdbms.drop database
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'builder/builder.rb'
|
|
4
|
+
|
|
5
|
+
module Prick::SubCommand
|
|
6
|
+
def self.fox(database, username, files)
|
|
7
|
+
Command.command "fox --state=#{FOX_STATE_PATH} --exec #{database} #{files.join(" ")}"
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
__END__
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Timer.on! if timer
|
|
15
|
+
time "Prick::Command#build" do
|
|
16
|
+
begin
|
|
17
|
+
super_conn = PgConn.new
|
|
18
|
+
conn = nil
|
|
19
|
+
builder = nil
|
|
20
|
+
|
|
21
|
+
time "Load build object" do
|
|
22
|
+
if super_conn.rdbms.exist? database
|
|
23
|
+
conn = PgConn.new(database, username)
|
|
24
|
+
super_conn.rdbms.empty!(database)
|
|
25
|
+
else
|
|
26
|
+
super_conn.rdbms.create database, owner: username
|
|
27
|
+
conn = PgConn.new(database, username)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
builder = Prick::Build::Builder.new(conn, builddir)
|
|
31
|
+
builder.pool.delete_schema(builder.pool.after_schema(schema)) if schema
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
case dump
|
|
35
|
+
when :nodes; builder.nodes.reject { |node| node.is_a?(Build::BuildNode) }.map &:dump
|
|
36
|
+
when :allnodes; builder.nodes.map &:dump
|
|
37
|
+
when :batches; builder.dump
|
|
38
|
+
when nil;
|
|
39
|
+
else
|
|
40
|
+
raise Prick::Error, "Illegal dump type: #{dump.inspect}"
|
|
41
|
+
end && exit
|
|
42
|
+
|
|
43
|
+
time "Execute build object" do
|
|
44
|
+
builder.execute conn
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
rescue Prick::Error => ex
|
|
48
|
+
$stderr.puts ex.message
|
|
49
|
+
exit 1
|
|
50
|
+
|
|
51
|
+
rescue ::Command::Error => ex
|
|
52
|
+
$stderr.puts ex.message
|
|
53
|
+
exit 1
|
|
54
|
+
|
|
55
|
+
ensure
|
|
56
|
+
super_conn&.terminate
|
|
57
|
+
conn&.terminate
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
module Prick::SubCommand
|
|
4
|
+
def self.init(dir, name, title, database, username)
|
|
5
|
+
if dir
|
|
6
|
+
!File.exist?(dir) or raise Prick::Error, "Directory #{dir} exists"
|
|
7
|
+
FileUtils.mkdir_p(dir)
|
|
8
|
+
Dir.chdir(dir)
|
|
9
|
+
else
|
|
10
|
+
dir = "."
|
|
11
|
+
end
|
|
12
|
+
name ||= File.basename(Dir.getwd)
|
|
13
|
+
title ||= name
|
|
14
|
+
database ||= name
|
|
15
|
+
username ||= name
|
|
16
|
+
|
|
17
|
+
Command.command %(
|
|
18
|
+
git init .
|
|
19
|
+
cp -a #{SHARE_PATH}/init/. .
|
|
20
|
+
git add .
|
|
21
|
+
git commit -am "Initial import"
|
|
22
|
+
), fail: false
|
|
23
|
+
|
|
24
|
+
Command.status == 0 or raise Prick::Fail, "Init script failed"
|
|
25
|
+
|
|
26
|
+
state = State.new
|
|
27
|
+
state.name = name
|
|
28
|
+
state.title = title
|
|
29
|
+
state.prick_version = PrickVersion.new VERSION
|
|
30
|
+
state.version = PrickVersion.new("0.0.0")
|
|
31
|
+
state.environment = :development
|
|
32
|
+
state.database = database
|
|
33
|
+
state.username = username
|
|
34
|
+
state.save
|
|
35
|
+
|
|
36
|
+
Command.command %(
|
|
37
|
+
set -e
|
|
38
|
+
git commit -am "Release 0.0.0"
|
|
39
|
+
git tag v0.0.0
|
|
40
|
+
), fail: false
|
|
41
|
+
|
|
42
|
+
Command.status == 0 or raise Prick::Fail, "Init script failed"
|
|
43
|
+
|
|
44
|
+
[dir, state]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'builder/builder.rb'
|
|
4
|
+
|
|
5
|
+
module Prick::SubCommand
|
|
6
|
+
def self.make(database, username, schema, timer: nil, dump: nil)
|
|
7
|
+
Timer.on! if timer
|
|
8
|
+
time "Prick::Command#build" do
|
|
9
|
+
begin
|
|
10
|
+
super_conn = PgConn.new
|
|
11
|
+
conn = nil
|
|
12
|
+
builder = nil
|
|
13
|
+
built_at = EPOCH
|
|
14
|
+
clean = false
|
|
15
|
+
create_schemas = []
|
|
16
|
+
|
|
17
|
+
time "Load build object" do
|
|
18
|
+
if super_conn.rdbms.exist? database
|
|
19
|
+
conn = PgConn.new(database, username)
|
|
20
|
+
if conn.schema.exist_table? "prick", "versions"
|
|
21
|
+
built_at = conn.value("select built_at from prick.versions")
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
super_conn.rdbms.create database, owner: username
|
|
25
|
+
conn = PgConn.new(database, username)
|
|
26
|
+
clean = true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
builder = Prick::Build::Builder.new(conn, "schema", clean)
|
|
30
|
+
|
|
31
|
+
if schema
|
|
32
|
+
builder.pool.after_schema(schema).each { |schema|
|
|
33
|
+
conn.schema.drop(schema, cascade: true)
|
|
34
|
+
builder.pool.delete_schema(schema)
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
touched_nodes = builder.nodes.select { |node| File.mtime(node.path) > built_at }
|
|
39
|
+
touched_phases = touched_nodes.map(&:phase).uniq.compact
|
|
40
|
+
touched_kinds = touched_nodes.map(&:kind).uniq.compact
|
|
41
|
+
touched_schema = touched_nodes.first&.schema
|
|
42
|
+
missing_schema = builder.schemas.find { |schema| !conn.schema.exist?(schema) }
|
|
43
|
+
build_schema = builder.schemas.find { |schema| [touched_schema, missing_schema].include? schema }
|
|
44
|
+
|
|
45
|
+
if build_schema.nil?
|
|
46
|
+
puts "#{database} is up to date"
|
|
47
|
+
exit
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if touched_phases.include?(:decl) || touched_phases.empty?
|
|
51
|
+
create_schemas = [build_schema] + builder.pool.after_schema(build_schema)
|
|
52
|
+
create_schemas.each { |schema| conn.schema.drop(schema, cascade: true) }
|
|
53
|
+
builder.pool.delete_schema(builder.pool.before_schema(build_schema), exclude: [:seed])
|
|
54
|
+
elsif touched_phases.include?(:init) || touched_phases.include?(:term)
|
|
55
|
+
builder.pool.clear(:decl, :seed)
|
|
56
|
+
elsif touched_phases.include?(:seed)
|
|
57
|
+
builder.pool.clear(:init, :decl, :term)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
builder.group
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
case dump
|
|
64
|
+
when :nodes; builder.nodes.reject { |node| node.is_a?(Build::BuildNode) }.map &:dump
|
|
65
|
+
when :allnodes; builder.nodes.map &:dump
|
|
66
|
+
when :batches; builder.dump
|
|
67
|
+
when nil;
|
|
68
|
+
else
|
|
69
|
+
raise Prick::Error, "Illegal dump type: #{dump.inspect}"
|
|
70
|
+
end
|
|
71
|
+
exit if dump
|
|
72
|
+
|
|
73
|
+
time "Execute build object" do
|
|
74
|
+
builder.execute(conn, create_schemas: create_schemas)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
rescue Prick::Build::Error => ex
|
|
78
|
+
$stderr.puts ex.message
|
|
79
|
+
exit 1
|
|
80
|
+
|
|
81
|
+
rescue Command::Error => ex
|
|
82
|
+
$stderr.puts ex.message
|
|
83
|
+
exit 1
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
__END__
|
|
91
|
+
require 'prick_build.rb'
|
|
92
|
+
|
|
93
|
+
require 'pg_conn'
|
|
94
|
+
|
|
95
|
+
require 'ruby-prof'
|
|
96
|
+
|
|
97
|
+
DATABASE = "mikras"
|
|
98
|
+
USERNAME = "mikras"
|
|
99
|
+
|
|
100
|
+
#PROFILE = true
|
|
101
|
+
PROFILE = false
|
|
102
|
+
TIME = true
|
|
103
|
+
#TIME = false
|
|
104
|
+
|
|
105
|
+
EPOCH = Time.at(0).utc
|
|
106
|
+
|
|
107
|
+
schema = ARGV.first
|
|
108
|
+
|
|
109
|
+
time "Program" do
|
|
110
|
+
RubyProf.start if PROFILE
|
|
111
|
+
begin
|
|
112
|
+
conn = nil
|
|
113
|
+
builder = nil
|
|
114
|
+
built_at = EPOCH
|
|
115
|
+
clean = false
|
|
116
|
+
create_schema = true
|
|
117
|
+
|
|
118
|
+
time "Load build object" do
|
|
119
|
+
PgConn.new { |super_conn|
|
|
120
|
+
if super_conn.rdbms.exist? DATABASE
|
|
121
|
+
conn = PgConn.new(DATABASE)
|
|
122
|
+
if conn.schema.exist_table? "prick", "versions"
|
|
123
|
+
built_at = conn.value("select built_at from prick.versions")
|
|
124
|
+
end
|
|
125
|
+
else
|
|
126
|
+
super_conn.rdbms.create DATABASE, owner: USERNAME
|
|
127
|
+
conn = PgConn.new(DATABASE)
|
|
128
|
+
clean = true
|
|
129
|
+
end
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
builder = Prick::Build::Builder.new(conn, "schema", clean)
|
|
133
|
+
|
|
134
|
+
if schema
|
|
135
|
+
builder.pool.after_schema(schema).each { |schema|
|
|
136
|
+
conn.schema.drop(schema, cascade: true)
|
|
137
|
+
builder.pool.delete_schema(schema)
|
|
138
|
+
}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
touched_nodes = builder.nodes.select { |node| File.mtime(node.path) > built_at }
|
|
142
|
+
touched_phases = touched_nodes.map(&:phase).uniq.compact
|
|
143
|
+
touched_schema = touched_nodes.first&.schema
|
|
144
|
+
missing_schema = builder.schemas.find { |schema| !conn.schema.exist?(schema) }
|
|
145
|
+
build_schema = builder.schemas.find { |schema| [touched_schema, missing_schema].include? schema }
|
|
146
|
+
|
|
147
|
+
# puts "touched_nodes : #{touched_nodes.size} nodes"
|
|
148
|
+
# puts "touched_phases: #{touched_phases.inspect}"
|
|
149
|
+
# puts "touched_schema: #{touched_schema.inspect}"
|
|
150
|
+
# puts "missing_schema: #{missing_schema.inspect}"
|
|
151
|
+
# puts "build_schema : #{build_schema.inspect}"
|
|
152
|
+
|
|
153
|
+
# builder.pool.dump
|
|
154
|
+
|
|
155
|
+
if build_schema.nil?
|
|
156
|
+
puts "#{DATABASE} is up to date"
|
|
157
|
+
exit
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
if touched_phases.include?(:decl) || touched_phases.empty?
|
|
161
|
+
schemas = [build_schema] + builder.pool.after_schema(build_schema)
|
|
162
|
+
schemas.each { |schema| conn.schema.drop(schema, cascade: true) }
|
|
163
|
+
builder.pool.delete_schema(builder.pool.before_schema(build_schema))
|
|
164
|
+
elsif touched_phases.include?(:init) || touched_phases.include?(:term)
|
|
165
|
+
builder.pool.clear(:decl, :seed)
|
|
166
|
+
create_schema = false
|
|
167
|
+
elsif touched_phases.include?(:seed)
|
|
168
|
+
builder.pool.clear(:init, :decl, :term)
|
|
169
|
+
create_schema = false
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# builder.pool.dump
|
|
173
|
+
builder.group
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# builder.dump
|
|
177
|
+
# p builder.schemas
|
|
178
|
+
# exit
|
|
179
|
+
|
|
180
|
+
time "Execute build object" do
|
|
181
|
+
builder.execute(conn, create_schema: create_schema)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
rescue Prick::Build::Error => ex
|
|
185
|
+
$stderr.puts ex.message
|
|
186
|
+
exit 1
|
|
187
|
+
|
|
188
|
+
rescue Command::Error => ex
|
|
189
|
+
$stderr.puts ex.message
|
|
190
|
+
exit 1
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
if PROFILE
|
|
195
|
+
profile = RubyProf.stop
|
|
196
|
+
# printer = RubyProf::GraphHtmlPrinter.new(profile)
|
|
197
|
+
printer = RubyProf::CallStackPrinter.new(profile)
|
|
198
|
+
File.open("t.html", "w") { |file|
|
|
199
|
+
printer.print(file, :min_percent => 2)
|
|
200
|
+
}
|
|
201
|
+
end
|
|
202
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
module Prick
|
|
3
|
+
module SubCommand
|
|
4
|
+
# def self.migrate(database, username, file) TODO
|
|
5
|
+
def self.migrate(database, username, file: nil)
|
|
6
|
+
PgConn.new(database, username) { |conn|
|
|
7
|
+
conn.schema.exist_relation? "prick", "versions" or
|
|
8
|
+
raise Prick::Fail, "Can't read version from database"
|
|
9
|
+
|
|
10
|
+
from_version = PrickVersion.new(conn.value "select version from prick.versions") or
|
|
11
|
+
raise Prick::Fail, "Illegal version in table prick.versions"
|
|
12
|
+
|
|
13
|
+
if file
|
|
14
|
+
conn.transaction {
|
|
15
|
+
conn.exec File.read(file)
|
|
16
|
+
}
|
|
17
|
+
else
|
|
18
|
+
to_version = Prick.state.version
|
|
19
|
+
from_version != to_version or raise Prick::Fail, "Already up to date"
|
|
20
|
+
from_version < to_version or raise Prick::Fail, "Can't migrate backwards"
|
|
21
|
+
|
|
22
|
+
migration_dir = "#{MIGRATION_DIR}/#{from_version}"
|
|
23
|
+
File.directory? migration_dir or
|
|
24
|
+
raise Prick::Fail, "Can't migrate from #{from_version} to #{to_version}"
|
|
25
|
+
|
|
26
|
+
puts "Migrating from #{from_version} to #{to_version}"
|
|
27
|
+
|
|
28
|
+
builder = Prick::Build::Builder.new(conn, migration_dir)
|
|
29
|
+
conn.transaction {
|
|
30
|
+
builder.execute conn
|
|
31
|
+
conn.exec File.read(SCHEMA_VERSION_PATH)
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
}
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
module Prick
|
|
3
|
+
module SubCommand
|
|
4
|
+
def self.release(kind)
|
|
5
|
+
constrain kind, :major, :minor, :patch
|
|
6
|
+
|
|
7
|
+
Git.clean? or raise "Won't release: Repository is dirty"
|
|
8
|
+
Git.synchronized? or raise "Won't release: Repository is not synchronized with origin"
|
|
9
|
+
|
|
10
|
+
version = Prick.state.version.increment!(kind).to_s
|
|
11
|
+
Prick.state.save
|
|
12
|
+
|
|
13
|
+
Git.add(Prick.state.file)
|
|
14
|
+
Git.add(Prick.state.schema_file)
|
|
15
|
+
Git.commit "Release #{version}"
|
|
16
|
+
Git.tag.create "v#{version}"
|
|
17
|
+
Git.branch.create version
|
|
18
|
+
Git.push
|
|
19
|
+
|
|
20
|
+
puts version
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'builder/builder.rb'
|
|
4
|
+
|
|
5
|
+
module Prick::SubCommand
|
|
6
|
+
def self.setup(database, username)
|
|
7
|
+
conn = PgConn.new
|
|
8
|
+
if !conn.role.exist? username
|
|
9
|
+
# FIXME Should not be created as superuser but we can't do that before we
|
|
10
|
+
# have a super: option in build
|
|
11
|
+
conn.role.create username, superuser: true, can_login: true, create_role: true
|
|
12
|
+
end
|
|
13
|
+
if !conn.rdbms.exist? database
|
|
14
|
+
conn.rdbms.create database, owner: username
|
|
15
|
+
end
|
|
16
|
+
builder = Prick::Build::Builder.new(conn, "schema")
|
|
17
|
+
# TODO Run builder setup scrips
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'builder/builder.rb'
|
|
4
|
+
|
|
5
|
+
module Prick::SubCommand
|
|
6
|
+
def self.teardown(database, username)
|
|
7
|
+
conn = PgConn.new # Superuser connection
|
|
8
|
+
if conn.rdbms.exist? database
|
|
9
|
+
conn.rdbms.drop database
|
|
10
|
+
end
|
|
11
|
+
if conn.role.exist? username
|
|
12
|
+
conn.role.drop username, cascade: true
|
|
13
|
+
end
|
|
14
|
+
builder = Prick::Build::Builder.new(conn, "schema")
|
|
15
|
+
# TODO Run builder teardown scrips
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
data/prick.gemspec
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
#lib = File.expand_path("../lib", __FILE__)
|
|
5
|
-
#$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
|
-
#require "prick/version"
|
|
7
|
-
require_relative 'lib/prick/version'
|
|
3
|
+
require_relative "lib/prick/version"
|
|
8
4
|
|
|
9
5
|
Gem::Specification.new do |spec|
|
|
10
6
|
spec.name = "prick"
|
|
@@ -15,39 +11,54 @@ Gem::Specification.new do |spec|
|
|
|
15
11
|
spec.summary = "A release control and management system for postgresql"
|
|
16
12
|
spec.description = "A release control and management system for postgresql"
|
|
17
13
|
spec.homepage = "http://www.nowhere.com/"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
# spec.metadata["homepage_uri"] = spec.homepage
|
|
21
|
-
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
|
22
|
-
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
|
14
|
+
# spec.required_ruby_version = "~> 2.7.1"
|
|
23
15
|
|
|
24
16
|
# Specify which files should be added to the gem when it is released.
|
|
25
17
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
26
|
-
spec.files
|
|
27
|
-
`git ls-files -z`.split("\x0").reject
|
|
18
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
19
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
20
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features|old)/|\.(?:git|travis|circleci)|appveyor)})
|
|
21
|
+
end
|
|
28
22
|
end
|
|
29
23
|
spec.bindir = "exe"
|
|
30
|
-
spec.executables = spec.files.grep(%r{
|
|
24
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
31
25
|
spec.require_paths = ["lib"]
|
|
32
26
|
|
|
33
|
-
#
|
|
34
|
-
spec.add_dependency "
|
|
27
|
+
# Uncomment to register a new dependency of your gem
|
|
28
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
|
29
|
+
|
|
30
|
+
# For more information and examples about making a new gem, checkout our
|
|
31
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
|
32
|
+
|
|
33
|
+
# Add your production dependencies here
|
|
34
|
+
# spec.add_dependency GEM [, VERSION]
|
|
35
35
|
spec.add_dependency "semantic"
|
|
36
|
-
spec.add_dependency "indented_io"
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
spec.add_dependency "boolean"
|
|
37
|
+
spec.add_dependency "indented_io"
|
|
40
38
|
spec.add_dependency "constrain"
|
|
41
|
-
spec.add_dependency "
|
|
39
|
+
spec.add_dependency "forward_to"
|
|
40
|
+
spec.add_dependency "bootsnap"
|
|
41
|
+
|
|
42
|
+
# Add your development dependencies here
|
|
43
|
+
# spec.add_development_dependency GEM [, VERSION]
|
|
44
|
+
spec.add_development_dependency "ruby-prof"
|
|
45
|
+
|
|
46
|
+
# Remove when fox goes a gem
|
|
42
47
|
spec.add_dependency "pg"
|
|
43
48
|
spec.add_dependency "dry-inflector"
|
|
49
|
+
spec.add_dependency "boolean"
|
|
50
|
+
spec.add_dependency "developer_exceptions"
|
|
51
|
+
spec.add_dependency "shellopts", "~> 2.0.23"
|
|
44
52
|
|
|
45
53
|
# In development mode override load paths for gems whose source are located
|
|
46
54
|
# as siblings of this project directory
|
|
47
55
|
if File.directory?("#{__dir__}/.git")
|
|
48
|
-
local_projects = Dir["../*"].select { |path|
|
|
56
|
+
local_projects = Dir["../*"].select { |path|
|
|
49
57
|
File.directory?(path) && File.exist?("#{path}/Gemfile")
|
|
50
58
|
}.map { |relpath| "#{File.absolute_path(relpath)}/lib" }
|
|
51
59
|
$LOAD_PATH.unshift *local_projects
|
|
52
60
|
end
|
|
61
|
+
|
|
62
|
+
# Also un-comment in spec/spec_helper to use simplecov
|
|
63
|
+
# spec.add_development_dependency "simplecov"
|
|
53
64
|
end
|