prick 0.2.0 → 0.7.0
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/.gitignore +6 -5
- data/Gemfile +4 -1
- data/TODO +10 -0
- data/doc/prick.txt +114 -0
- data/exe/prick +328 -402
- data/lib/ext/fileutils.rb +18 -0
- data/lib/ext/forward_method.rb +18 -0
- data/lib/ext/shortest_path.rb +44 -0
- data/lib/prick.rb +20 -10
- data/lib/prick/branch.rb +254 -0
- data/lib/prick/builder.rb +164 -0
- data/lib/prick/cache.rb +34 -0
- data/lib/prick/command.rb +19 -11
- data/lib/prick/constants.rb +122 -48
- data/lib/prick/database.rb +28 -20
- data/lib/prick/diff.rb +125 -0
- data/lib/prick/exceptions.rb +15 -3
- data/lib/prick/git.rb +77 -30
- data/lib/prick/head.rb +183 -0
- data/lib/prick/migration.rb +40 -200
- data/lib/prick/program.rb +493 -0
- data/lib/prick/project.rb +523 -351
- data/lib/prick/rdbms.rb +4 -13
- data/lib/prick/schema.rb +16 -90
- data/lib/prick/share.rb +64 -0
- data/lib/prick/state.rb +192 -0
- data/lib/prick/version.rb +62 -29
- data/libexec/strip-comments +33 -0
- data/make_releases +48 -345
- data/make_schema +10 -0
- data/prick.gemspec +14 -23
- data/share/diff/diff.after-tables.sql +4 -0
- data/share/diff/diff.before-tables.sql +4 -0
- data/share/diff/diff.tables.sql +8 -0
- data/share/migration/diff.tables.sql +8 -0
- data/share/migration/features.yml +6 -0
- data/share/migration/migrate.sql +3 -0
- data/share/migration/migrate.yml +8 -0
- data/share/migration/tables.sql +3 -0
- data/share/schema/build.yml +14 -0
- data/share/schema/schema.sql +5 -0
- data/share/schema/schema/build.yml +3 -0
- data/share/schema/schema/prick/build.yml +14 -0
- data/share/schema/schema/prick/data.sql +7 -0
- data/share/schema/schema/prick/schema.sql +5 -0
- data/share/{schemas/prick/schema.sql → schema/schema/prick/tables.sql} +2 -5
- data/{file → share/schema/schema/public/.keep} +0 -0
- data/share/schema/schema/public/build.yml +14 -0
- data/share/schema/schema/public/schema.sql +3 -0
- data/test_assorted +192 -0
- data/test_feature +112 -0
- data/test_refactor +34 -0
- data/test_single_dev +83 -0
- metadata +43 -68
- data/lib/prick/build.rb +0 -376
- data/lib/prick/migra.rb +0 -22
- data/share/schemas/prick/data.sql +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd62ad39d6f79354d9eb4e68e102cbe2fa45c3c83f3bb670bb67cc91faab2b6c
|
4
|
+
data.tar.gz: 1802956bd55eafd32b16ff2d473e7b8c4f22ffaa2526ab83afb1c8d271b3fe37
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c8b1553cba9e5afe792b1f3119ffb9b85e23626d830b752dc98ee5bd28e4c7eeaf8e7b50acb52cfe9e32dcf935d8dcd99694bf2d1d29ebd830c1a9abcb852f38
|
7
|
+
data.tar.gz: 3a189a2dff6750afc58f01189dc86fd671b605f5281e17d725607483e0d2f24603f54cc9071145dcfa681109d971da8736a5e81be454b3b1d3d3ee055060f92f
|
data/.gitignore
CHANGED
@@ -19,10 +19,11 @@
|
|
19
19
|
|
20
20
|
# Put your personal ignore files in /home/clr/.config/git/ignore
|
21
21
|
|
22
|
-
# Temporary ignores
|
23
|
-
/releases/
|
24
|
-
/migrations/
|
25
|
-
/prick.sh
|
26
|
-
|
27
22
|
# Ignore bundle binstubs
|
28
23
|
/bin/prick
|
24
|
+
|
25
|
+
# Ignore development testing dir
|
26
|
+
/dir
|
27
|
+
|
28
|
+
# Ignore stove-away directory
|
29
|
+
/hold
|
data/Gemfile
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
3
|
+
git_source(:github) {|repo_name| "https://github.com/clrgit/#{repo_name}" }
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in prick.gemspec
|
6
6
|
gemspec
|
7
|
+
|
8
|
+
gem "rake", "~> 12.0"
|
9
|
+
gem "rspec", "~> 3.0"
|
data/TODO
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
|
2
|
+
o Check for commits to tags
|
3
|
+
o Accumulate version history in prick.versions instead of just having the newest
|
4
|
+
o Using rc's in migration syntax: fork-version-fork-version.rc1 ?
|
5
|
+
o Make it possible to execute prick in any subdirecty instead of only in the root
|
6
|
+
o Hack migra to create separate file(s) for table changes
|
7
|
+
o Also execute subject/ directory if only a subject.sql is found. subject.yml
|
8
|
+
should still override everything
|
9
|
+
o Track included files - this will make dependency checks much easier
|
10
|
+
|
data/doc/prick.txt
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
MIGRATION STATE FILES
|
4
|
+
.prick-migration (State file)
|
5
|
+
version: Version
|
6
|
+
The target version. The result of running the migration on the base
|
7
|
+
release
|
8
|
+
base_version: Version
|
9
|
+
Base version. Running the migration on a base release yields a release
|
10
|
+
of with the same version as the `version` property
|
11
|
+
|
12
|
+
The 0.0.0 version has base_version equal to nil. A Feature has version
|
13
|
+
equal to its base version.
|
14
|
+
|
15
|
+
Note that while a release's .prick-migration file lives in the release
|
16
|
+
directory, it's .prick-features file and the migrations lives in the
|
17
|
+
directory of the base release. This separation supports the
|
18
|
+
single-developer workflow where the next release is not known beforehand
|
19
|
+
|
20
|
+
.prick-features (State file)
|
21
|
+
features: Array
|
22
|
+
A list of features versions
|
23
|
+
|
24
|
+
MIGRATION FILES
|
25
|
+
migrate.sql
|
26
|
+
features.sql
|
27
|
+
diff.sql
|
28
|
+
|
29
|
+
|
30
|
+
MIGRATION FILE STRUCTURE
|
31
|
+
releases/
|
32
|
+
0.0.0/
|
33
|
+
.prick-migration -> version: 0.0.0, base_version: nil
|
34
|
+
.prick-features -> [feature_a]
|
35
|
+
feature_a/
|
36
|
+
.prick-migration -> version: nil, base_version: 0.0.0
|
37
|
+
.prick-features -> []
|
38
|
+
feature_b/ (rebased)
|
39
|
+
.prick-migration -> version: 0.2.0, base_version: 0.2.0-pre.1
|
40
|
+
.prick-features -> []
|
41
|
+
|
42
|
+
0.1.0/
|
43
|
+
.prick-migration -> version: 0.1.0, base_version: 0.0.0
|
44
|
+
feature_b/ symlinks to ../0.0.0/feature_b/
|
45
|
+
|
46
|
+
0.1.0/ (wip - single developer work flow)
|
47
|
+
.prick-migration -> version: 0.1.0, base_version: 0.0.0
|
48
|
+
.prick-features -> [feature_c]
|
49
|
+
feature_c/
|
50
|
+
...
|
51
|
+
|
52
|
+
0.2.0/ (doing a pre-release)
|
53
|
+
.prick-migration -> version: 0.2.0-pre.1, base_version: 0.1.0
|
54
|
+
|
55
|
+
migrations/
|
56
|
+
0.0.0_0.1.0/
|
57
|
+
.prick-migration -> version: 0.1.0, base_version: 0.0.0
|
58
|
+
.prick-features -> []
|
59
|
+
|
60
|
+
|
61
|
+
NOTES
|
62
|
+
#
|
63
|
+
# Distinguish between running a migration 0.1.0 -> 0.2.0 and running the
|
64
|
+
# migration in the 0.2.0 directory in the single-developer workflow
|
65
|
+
#
|
66
|
+
# prick migrate
|
67
|
+
# On a tag: Migrate to that tag
|
68
|
+
# On a branch: Run migrations in the release directory
|
69
|
+
#
|
70
|
+
# prick migrate 0.2.0 <- the version number reflects where to find the migration
|
71
|
+
# Runs the migration files in the release directory
|
72
|
+
#
|
73
|
+
# prick migrate 0.1.0
|
74
|
+
# Runs the migration files in the base release directory
|
75
|
+
#
|
76
|
+
#
|
77
|
+
# prick build
|
78
|
+
# Builds the current schema into the project database
|
79
|
+
#
|
80
|
+
# prick build 0.1.0
|
81
|
+
# Builds the given schema into a versioned database
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
######################
|
96
|
+
|
97
|
+
PRICK FILES
|
98
|
+
./prick-version
|
99
|
+
Contains just one line with the version of the prick command that should be
|
100
|
+
used with this project (eg. 'prick-0.1.0'). Prick checks this file at
|
101
|
+
startup and fails if the required version doesn't match the current command
|
102
|
+
|
103
|
+
./prick
|
104
|
+
project_name
|
105
|
+
Name of the project
|
106
|
+
|
107
|
+
./releases/*/.prick
|
108
|
+
base_version
|
109
|
+
The base version of this release. nil for release 0.0.0
|
110
|
+
features
|
111
|
+
List of features in a release based on this release. Initially empty
|
112
|
+
but filled in when the directory is prepared for a subsequent release.
|
113
|
+
To find the set of features in the current release, inspect the prick
|
114
|
+
file of the base_version in this branch
|
data/exe/prick
CHANGED
@@ -1,461 +1,335 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'prick.rb'
|
4
|
+
require 'prick/program.rb'
|
4
5
|
|
5
6
|
require 'shellopts'
|
6
|
-
|
7
|
+
|
7
8
|
require 'tempfile'
|
8
|
-
require 'ext/algorithm.rb'
|
9
9
|
|
10
10
|
include ShellOpts
|
11
|
+
include Prick
|
11
12
|
|
12
|
-
# TODO: Backup & restore
|
13
13
|
SPEC = %(
|
14
|
-
n,name=NAME
|
15
|
-
C,directory=DIR
|
16
|
-
h,help
|
17
|
-
v,verbose
|
18
|
-
q,quiet
|
19
|
-
version
|
20
|
-
|
21
|
-
init!
|
22
|
-
info!
|
23
|
-
status!
|
24
|
-
history!
|
25
|
-
|
26
|
-
checkout!
|
27
|
-
|
28
|
-
feature!
|
29
|
-
rebase!
|
30
|
-
|
31
|
-
create! create.release! create.prerelease! create.feature! create.migration!
|
32
|
-
increment! increment.prerelease!
|
33
|
-
|
34
|
-
prepare! prepare.release! prepare.prerelease! prepare.feature! prepare.migration!
|
35
|
-
include!
|
36
|
-
commit!
|
37
|
-
prerelease!
|
38
|
-
release!
|
39
|
-
|
40
|
-
list! list.databases! list.releases! list.prereleases!
|
41
|
-
build!
|
42
|
-
use! f,file=FILE
|
43
|
-
load! f,file=FILE
|
44
|
-
reload! f,file=FILE
|
45
|
-
unload!
|
46
|
-
clean!
|
47
|
-
|
48
|
-
migrate!
|
49
|
-
)
|
50
|
-
|
51
|
-
USAGE = "-h -v -n NAME -C DIR COMMAND"
|
52
|
-
|
53
|
-
HELP = %(
|
54
|
-
NAME
|
55
|
-
prick - Database version management
|
56
|
-
|
57
|
-
USAGE
|
58
|
-
prick -v -n NAME -C DIR -h <command>
|
59
|
-
|
60
|
-
OPTIONS
|
61
|
-
-n, --name=NAME
|
14
|
+
-n,name=NAME
|
62
15
|
Name of project. Defauls to the environment variable `PRICK_PROJECT` if
|
63
16
|
set and else the name of the current directory
|
64
17
|
|
65
|
-
|
66
|
-
Change to directory DIR before anything else
|
18
|
+
-C,directory=DIR
|
19
|
+
Change to directory DIR before doing anything else
|
67
20
|
|
68
|
-
|
21
|
+
-h,help COMMAND...
|
69
22
|
Print this page
|
70
23
|
|
71
|
-
|
72
|
-
Be verbose
|
24
|
+
+v,verbose
|
25
|
+
Be verbose. Repeated --verbose options increase the verbosity level
|
73
26
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
COMMANDS
|
78
|
-
INFO COMMANDS
|
79
|
-
init [DIR]
|
80
|
-
Initialize a project directory
|
27
|
+
-q,quiet
|
28
|
+
Be quiet
|
81
29
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
status
|
86
|
-
Short status
|
87
|
-
|
88
|
-
GENERAL COMMANDS
|
89
|
-
checkout
|
90
|
-
As git checkout but does some extra work behind the scenes
|
91
|
-
|
92
|
-
migrate
|
93
|
-
Migrate from the current branch in the database to the current branch
|
94
|
-
|
95
|
-
|
96
|
-
DEVELOPER COMMANDS
|
97
|
-
create feature FEATURE
|
98
|
-
Create a new feature branch and a feature directory under
|
99
|
-
features/<base-version>. Note that the base version is the base version
|
100
|
-
of the pre-release
|
101
|
-
|
102
|
-
Features are named <feature>-<base-version>
|
103
|
-
|
104
|
-
prepare migration
|
105
|
-
Create migration files from the base release to the current schema. It
|
106
|
-
does not overwrite existing migration files
|
107
|
-
|
108
|
-
rebase VERSION
|
109
|
-
Rebase the feature to HEAD of the release. The rebased feature lives on
|
110
|
-
a branch of its own and have a symlink from the new base release to the
|
111
|
-
feature implementation in the original release. Rebased features are
|
112
|
-
named <feature>-<rebase-version>
|
113
|
-
|
114
|
-
|
115
|
-
RELEASE MANAGER COMMANDS
|
116
|
-
migrate VERSION|patch|minor|major
|
117
|
-
Prepare migration from current release to the given version. The branch
|
118
|
-
will be named <old-version>_<new-version>. Note that the generated
|
119
|
-
files don't include data migrations so it may be easier to first create a
|
120
|
-
prerelease and include missing features and then use that release as base
|
121
|
-
for an empty migration release that just changes the version number
|
30
|
+
--version
|
31
|
+
Print prick version
|
122
32
|
|
123
|
-
|
33
|
+
init! -u,user=USER [DIR]
|
34
|
+
Initialize a project in the given directory. DIR defaults to the current
|
35
|
+
directory. The USER is the postgres user, it defaults to the project name
|
124
36
|
|
125
|
-
|
126
|
-
|
127
|
-
features directory for the _base_ version. If version is one of the
|
128
|
-
names patch, minor, or major then the version is constructed by
|
129
|
-
incrementing the given part of the base release's version
|
37
|
+
info!
|
38
|
+
Print project information
|
130
39
|
|
131
|
-
|
132
|
-
|
40
|
+
list.releases! -m,migrations -c,cancelled
|
41
|
+
List releases. Include migration releases if the --migration option is
|
42
|
+
present and also include cancelled releases if the --cancelled option is
|
43
|
+
present
|
133
44
|
|
134
|
-
|
135
|
-
|
45
|
+
list.migrations!
|
46
|
+
List migrations
|
136
47
|
|
137
|
-
|
138
|
-
|
48
|
+
list.upgrades! [FROM [TO]]
|
49
|
+
List available upgrades
|
139
50
|
|
51
|
+
list.cache!
|
52
|
+
List cache files
|
140
53
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
54
|
+
build! -d,database=DATABASE -C,no-cache [TAG]
|
55
|
+
Build the current database from the content in the schemas/ directory.
|
56
|
+
With a tag the version is built into the associated versioned database
|
57
|
+
and the result is saved to cache unless the -C option is given. The -d
|
58
|
+
option overrides the default database
|
145
59
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
60
|
+
make! -d,database=DATABASE -C,no-cache [TAG]
|
61
|
+
Build the current database from the content in the schemas/ directory.
|
62
|
+
With a tag the associated versioned database is loaded from cache if
|
63
|
+
present. The -C option ignores the cache and the -d option overrides
|
64
|
+
the default database
|
150
65
|
|
151
|
-
|
152
|
-
|
66
|
+
make.clean! -a,all
|
67
|
+
Drop versioned databases and remove cached and other temporary files.
|
68
|
+
Also drop the project database if the -a option is given
|
153
69
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
reload [VERSION]
|
159
|
-
Clear the versioned database and reload the release from the cache
|
70
|
+
load! -d,database=DATABASE VERSION|FILE
|
71
|
+
Load the cached version or the file into the associated versioned
|
72
|
+
database. It is an error if the version hasn't been cached. The --database
|
73
|
+
argument overrides the database
|
160
74
|
|
161
|
-
|
162
|
-
|
163
|
-
|
75
|
+
save! VERSION [FILE]
|
76
|
+
Save the versioned database associated with version to the cache or the
|
77
|
+
given file
|
164
78
|
|
165
|
-
|
166
|
-
|
79
|
+
drop! -a,all [DATABASE]
|
80
|
+
Drop the given database or all versioned databases. The --all option also
|
81
|
+
drops the project database
|
167
82
|
|
83
|
+
diff! -m,mark -t,tables -T,notables
|
84
|
+
diff [FROM-DATABASE|FROM-VERSION [TO-DATABASE|TO-VERSION]]
|
85
|
+
Create a schema diff between the given databases or versions. Default
|
86
|
+
to-version is the current schema and default from-version is the base
|
87
|
+
version of this branch/tag
|
168
88
|
|
89
|
+
migrate!
|
90
|
+
Not yet implemented
|
91
|
+
|
92
|
+
prepare!
|
93
|
+
Prepare a release. Just a shorthand for 'prick prepare release'
|
94
|
+
|
95
|
+
prepare.release! [FORK]
|
96
|
+
Populate the current migration directory with migration files
|
97
|
+
|
98
|
+
prepare.feature! NAME
|
99
|
+
Create and populate a feature as a subdirectory of the current directory.
|
100
|
+
Also prepares the current release directory
|
101
|
+
|
102
|
+
prepare.migration! [FROM]
|
103
|
+
Create and populate a migration directory
|
104
|
+
|
105
|
+
prepare.schema! NAME
|
106
|
+
Create and populate a new schema directory. Existing files and
|
107
|
+
directories are kept
|
108
|
+
|
109
|
+
prepare.diff! [VERSION]
|
110
|
+
Not yet implemented
|
111
|
+
|
112
|
+
include.feature! FEATURE
|
113
|
+
Include the given feature in the current pre-release
|
114
|
+
|
115
|
+
check!
|
116
|
+
Check that the current migration applied to the base version yields the
|
117
|
+
same result as loading the current schema
|
118
|
+
|
119
|
+
create.release! [RELEASE]
|
120
|
+
Prepare a release and create release directory and migration file before
|
121
|
+
tagging and branching to a release branch. The RELEASE argument can be
|
122
|
+
left out if the current branch is a prerelease branch
|
123
|
+
|
124
|
+
create.prerelease! RELEASE
|
125
|
+
Prepare a release and create release directory and migration file before
|
126
|
+
branching to a prerelease branch
|
127
|
+
|
128
|
+
create.feature! NAME
|
129
|
+
Prepare a feature before branching to a feature branch
|
130
|
+
|
131
|
+
cancel!
|
132
|
+
Cancel a release. Just a shorthand for 'prick cancel release'
|
133
|
+
|
134
|
+
cancel.release!
|
135
|
+
Cancel a release. Since tags are immutable, the release is cancelled by
|
136
|
+
added a special cancel-tag to the release that makes prick ignore it
|
137
|
+
|
138
|
+
generate.migration!
|
139
|
+
Create a script to migrate the database
|
140
|
+
|
141
|
+
generate.schema!
|
142
|
+
Create a script to create the database
|
143
|
+
|
144
|
+
upgrade!
|
145
|
+
Migrate the database to match the current schema
|
146
|
+
|
147
|
+
backup! [FILE]
|
148
|
+
Saves a backup of the database to the given file or to the var/spool
|
149
|
+
directory
|
150
|
+
|
151
|
+
restore! [FILE]
|
152
|
+
Restore the database from the given backup file or from the latest backup
|
153
|
+
in the var/spool directory
|
169
154
|
)
|
170
155
|
|
171
|
-
INFO_PARAMS = {
|
172
|
-
"Releases": :releases,
|
173
|
-
"Pre-releases": :prereleases,
|
174
|
-
"Features": :features,
|
175
|
-
"Ignored releases": :ignored_release_nodes,
|
176
|
-
"Ignored features": :ignored_feature_nodes,
|
177
|
-
"Orphan disk features": :orphan_feature_nodes,
|
178
|
-
"Orphan disk releases": :orphan_release_nodes,
|
179
|
-
"Orphan git branches": :orphan_git_branches
|
180
|
-
}
|
181
|
-
|
182
|
-
def info(project)
|
183
|
-
for header, member in INFO_PARAMS
|
184
|
-
elements = project.send(member)
|
185
|
-
puts header
|
186
|
-
if elements.empty?
|
187
|
-
puts " [none]"
|
188
|
-
else
|
189
|
-
if member == :features
|
190
|
-
project.features.each { |release, features|
|
191
|
-
puts " #{release}"
|
192
|
-
features.each { |feature| puts " #{feature.feature}" }
|
193
|
-
}
|
194
|
-
else
|
195
|
-
elements.sort.each { |element| puts " #{element}" }
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
156
|
|
201
|
-
def compute_version(project, arg)
|
202
|
-
if arg.nil?
|
203
|
-
nil
|
204
|
-
elsif %w(major minor patch).include?(arg)
|
205
|
-
project.release.version.increment(arg.to_sym)
|
206
|
-
else
|
207
|
-
Prick::Version.new(arg)
|
208
|
-
end
|
209
|
-
end
|
210
157
|
|
211
|
-
opts, args = ShellOpts.
|
158
|
+
opts, args = ShellOpts.process(SPEC, ARGV)
|
212
159
|
|
213
160
|
# Handle --help
|
214
161
|
if opts.help?
|
215
|
-
|
216
|
-
file = Tempfile.new("prick")
|
217
|
-
file.puts HELP.split("\n").map { |l| l.sub(/^ /, "") }
|
218
|
-
file.flush
|
219
|
-
system "less #{file.path}"
|
220
|
-
ensure
|
221
|
-
file.close
|
222
|
-
end
|
162
|
+
ShellOpts.help
|
223
163
|
exit
|
224
|
-
end
|
164
|
+
end
|
225
165
|
|
226
166
|
# Handle --version
|
227
|
-
if opts.version?
|
228
|
-
puts "prick-#{
|
229
|
-
exit
|
167
|
+
if opts.version?
|
168
|
+
puts "prick-#{VERSION}"
|
169
|
+
exit
|
230
170
|
end
|
231
171
|
|
232
172
|
begin
|
233
173
|
# Honor -C option
|
234
|
-
if opts.directory
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
174
|
+
if opts.directory?
|
175
|
+
if File.exist?(opts.directory)
|
176
|
+
begin
|
177
|
+
Dir.chdir(opts.directory)
|
178
|
+
rescue Errno::ENOENT
|
179
|
+
raise Prick::Error, "Can't cd to '#{opts.directory}'"
|
180
|
+
end
|
181
|
+
else
|
182
|
+
raise Prick::Error, "Can't find directory: #{opts.directory}"
|
239
183
|
end
|
240
184
|
end
|
241
185
|
|
242
|
-
|
243
|
-
|
186
|
+
# Create program object
|
187
|
+
program = Program.new(quiet: opts.quiet?, verbose: opts.verbose?)
|
244
188
|
|
245
|
-
#
|
246
|
-
# constructed before the directory has been initialized
|
189
|
+
# Handle init command
|
247
190
|
if opts.subcommand == :init
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
puts "Initialized project #{name} in #{dir}" if !opts.quiet?
|
255
|
-
else
|
256
|
-
puts "Initialized project #{name}" if !opts.quiet?
|
257
|
-
end
|
258
|
-
else
|
259
|
-
project = Prick::Project.new(name)
|
260
|
-
|
261
|
-
case cmd = opts.subcommand
|
191
|
+
directory = args.expect(0..1)
|
192
|
+
name = opts.name || (directory && File.basename(directory)) || File.basename(Dir.getwd)
|
193
|
+
user = opts.init!.user || name
|
194
|
+
program.init(name, user, directory || ".")
|
195
|
+
exit 0
|
196
|
+
end
|
262
197
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
198
|
+
# Check prick version
|
199
|
+
file = PrickVersion.new
|
200
|
+
file.exist? or raise Prick::Error, "Can't find prick version file '#{file.path}'"
|
201
|
+
VERSION == file.read.to_s or
|
202
|
+
raise Prick::Fail, ".prick-version required prick-#{file.read} but you're using prick-#{VERSION}"
|
203
|
+
|
204
|
+
# TODO: Check for dirty detached head
|
205
|
+
|
206
|
+
# Expect a sub-command
|
207
|
+
opts.subcommand or raise Prick::Error, "Subcomand expected"
|
208
|
+
|
209
|
+
case opts.subcommand
|
210
|
+
when :info
|
211
|
+
args.expect(0)
|
212
|
+
program.info
|
213
|
+
|
214
|
+
when :list
|
215
|
+
command = opts.list!
|
216
|
+
case command.subcommand
|
217
|
+
when :releases;
|
218
|
+
obj = command.releases!
|
219
|
+
program.list_releases(migrations: obj.migrations?, cancelled: obj.cancelled?)
|
220
|
+
when :migrations; program.list_migrations
|
221
|
+
when :upgrades; program.list_upgrades(*args.expect(0..2).compact)
|
222
|
+
when :cache;
|
223
|
+
args.expect(0)
|
224
|
+
program.list_cache
|
225
|
+
when NilClass; raise Prick::Error, "list requires a releases|migrations|upgrades sub-command"
|
226
|
+
else
|
227
|
+
raise Prick::Internal, "Subcommand #{opts.subcommand}.#{command.subcommand} is not matched"
|
228
|
+
end
|
267
229
|
|
268
|
-
|
269
|
-
|
230
|
+
when :build
|
231
|
+
version = args.expect(0..1)
|
232
|
+
program.build(opts.build!.database, version, opts.build!.no_cache?)
|
270
233
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
print " (present)" if project.database.exist? && !project.database.loaded?
|
276
|
-
print " (using #{project.database.version})" if project.database.loaded?
|
277
|
-
else
|
278
|
-
print " [missing]" if !project.database.exist?
|
279
|
-
end
|
280
|
-
puts
|
281
|
-
|
282
|
-
puts "Releases"
|
283
|
-
project.releases.each { |release|
|
284
|
-
print " #{release}"
|
285
|
-
if release.database.exist?
|
286
|
-
if release.database.version
|
287
|
-
print " loaded"
|
288
|
-
else
|
289
|
-
print " (empty database)"
|
290
|
-
end
|
291
|
-
end
|
292
|
-
if release.cached?
|
293
|
-
print ", cached"
|
294
|
-
end
|
295
|
-
print " <#{release.database.name}>"
|
296
|
-
print "\n"
|
297
|
-
}
|
298
|
-
puts
|
299
|
-
info(project)
|
300
|
-
|
301
|
-
when :status
|
302
|
-
args.expect(0)
|
303
|
-
puts "On branch #{project.release}" + (project.dirty? ? " (dirty)" : "")
|
304
|
-
|
305
|
-
when :history
|
306
|
-
args.expect(0)
|
307
|
-
history = project.release.history
|
308
|
-
history.each { |release, features|
|
309
|
-
puts release.to_s
|
310
|
-
indent {
|
311
|
-
features.map { |feature|
|
312
|
-
puts "#{feature}, base release: #{feature.base_release}"
|
313
|
-
}
|
314
|
-
}
|
315
|
-
}
|
316
|
-
|
317
|
-
|
318
|
-
# GENERAL COMMANDS ######################################################
|
319
|
-
#
|
320
|
-
when :checkout
|
321
|
-
version = args.expect(1)
|
322
|
-
project.checkout(version)
|
323
|
-
puts "Checked out #{version}"
|
324
|
-
|
325
|
-
when :migrate
|
326
|
-
project.migrate
|
327
|
-
|
328
|
-
|
329
|
-
# DEVELOPER COMMANDS ####################################################
|
330
|
-
#
|
331
|
-
when :feature # Shorthand for 'create feature'
|
332
|
-
|
333
|
-
when :rebase
|
334
|
-
|
335
|
-
when :prepare
|
336
|
-
args.expect(0)
|
337
|
-
if object = opts.prepare.subcommand!
|
338
|
-
case object
|
339
|
-
when :migration
|
340
|
-
project.prepare_migration
|
341
|
-
puts "Prepared migration"
|
342
|
-
else
|
343
|
-
raise "Oops: subcommand #{opts.subcommand.inspect} not matched"
|
344
|
-
end
|
345
|
-
else
|
234
|
+
when :make
|
235
|
+
command = opts.make!
|
236
|
+
case command.subcommand
|
237
|
+
when :clean
|
346
238
|
args.expect(0)
|
347
|
-
|
348
|
-
puts "Prepared new release" if !opts.quiet?
|
349
|
-
end
|
350
|
-
|
351
|
-
|
352
|
-
# RELEASE MANAGER COMMANDS ##############################################
|
353
|
-
#
|
354
|
-
when :create
|
355
|
-
object = opts.create.subcommand!
|
356
|
-
release =
|
357
|
-
case object
|
358
|
-
when :release
|
359
|
-
version = compute_version(project, args.expect(0..1))
|
360
|
-
project.create_release(version)
|
361
|
-
when :prerelease
|
362
|
-
version = compute_version(project, args.expect(1))
|
363
|
-
project.create_prerelease(version)
|
364
|
-
when :feature
|
365
|
-
project.create_feature(args.expect(1))
|
366
|
-
else
|
367
|
-
raise "Oops: subcommand #{opts.subcommand.inspect} not matched"
|
368
|
-
end
|
369
|
-
puts "Created #{object} #{release.version}" if !opts.quiet?
|
370
|
-
|
371
|
-
when :increment # and 'increment prerelease'
|
372
|
-
args.expect(0)
|
373
|
-
release = project.increment_prerelease
|
374
|
-
puts "Created prerelease #{release.version}" if !opts.quiet?
|
375
|
-
|
376
|
-
when :release # Shorthand for 'create release'
|
377
|
-
version = compute_version(project, args.expect(0..1))
|
378
|
-
release = project.create_release(version)
|
379
|
-
puts "Created release #{release.version}" if !opts.quiet?
|
380
|
-
|
381
|
-
when :prerelease # Shorthand for 'create prerelease' and 'increment'
|
382
|
-
release =
|
383
|
-
if project.release?
|
384
|
-
version = compute_version(project, args.expect(1))
|
385
|
-
project.create_prerelease(version)
|
386
|
-
elsif project.prerelease?
|
387
|
-
args.expect(0)
|
388
|
-
project.increment_prerelease
|
389
|
-
end
|
390
|
-
puts "Created prerelease #{release.version}" if !opts.quiet?
|
391
|
-
|
392
|
-
when :include
|
393
|
-
name = args.expect(1)
|
394
|
-
project.include_feature(name)
|
395
|
-
puts "Included feature #{name}" if !opts.quiet?
|
396
|
-
puts "Please check changed files and then commit using 'prick commit'"
|
397
|
-
|
398
|
-
when :commit
|
399
|
-
msg = project.commit_feature
|
400
|
-
puts msg if !opts.quiet?
|
401
|
-
puts "Committed changes" if !opts.quiet?
|
402
|
-
|
403
|
-
|
404
|
-
# MANIPULATING DATABASES AND RELEASES ###################################
|
405
|
-
#
|
406
|
-
when :list
|
407
|
-
# TODO: Mark cached releases as such
|
408
|
-
args.expect(0)
|
409
|
-
case opts.list.subcommand
|
410
|
-
when :databases, nil; project.databases.map(&:name)
|
411
|
-
when :releases; project.releases.map(&:name)
|
412
|
-
when :prereleases; project.prereleases.map(&:version)
|
413
|
-
else
|
414
|
-
ShellOpts.error "Illegal list type: '#{opts.list.subcommand}"
|
415
|
-
end.each { |e| puts e }
|
416
|
-
|
417
|
-
when :build
|
418
|
-
version = args.expect(0..1)
|
419
|
-
project.build(version)
|
420
|
-
if version
|
421
|
-
puts "Built #{version}"
|
239
|
+
program.make_clean(command.clean!.all?)
|
422
240
|
else
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
241
|
+
version = args.expect(0..1)
|
242
|
+
program.make(opts.make!.database, version, opts.make!.no_cache?)
|
243
|
+
end
|
244
|
+
|
245
|
+
when :load
|
246
|
+
version_or_file = args.expect(1)
|
247
|
+
program.load(opts.load!.database, version_or_file)
|
248
|
+
|
249
|
+
when :save
|
250
|
+
version, file = args.expect(1..2)
|
251
|
+
program.save(version, file)
|
252
|
+
|
253
|
+
when :drop
|
254
|
+
program.drop(args.expect(0..1), opts.drop!.all)
|
255
|
+
|
256
|
+
when :diff
|
257
|
+
mark = opts.diff!.mark
|
258
|
+
tables = opts.diff!.tables
|
259
|
+
no_tables = opts.diff!.notables
|
260
|
+
tables.nil? && no_tables.nil? || tables ^ no_tables or
|
261
|
+
raise Error, "--tables and --no-tables options are exclusive"
|
262
|
+
select = tables ? :tables : (no_tables ? :no_tables : :all)
|
263
|
+
from, to = args.expect(0..2)
|
264
|
+
program.diff(from, to, mark, select)
|
265
|
+
|
266
|
+
when :migrate
|
267
|
+
raise NotYet
|
268
|
+
|
269
|
+
when :prepare
|
270
|
+
cmd = opts.prepare!.subcommand || :release
|
271
|
+
case cmd
|
272
|
+
when :release; program.prepare_release(args.expect(0..1))
|
273
|
+
when :feature; program.prepare_feature(args.expect(1))
|
274
|
+
when :migration; program.prepare_migration(args.expect(0..1))
|
275
|
+
when :schema; program.prepare_schema(args.expect(1))
|
276
|
+
when :diff; program.prepare_diff(args.expect(0..1))
|
277
|
+
else
|
278
|
+
raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
|
279
|
+
end
|
280
|
+
|
281
|
+
when :include
|
282
|
+
cmd = opts.include!.subcommand || :feature
|
283
|
+
case cmd
|
284
|
+
when :feature; program.include_feature(args.expect(1))
|
285
|
+
else
|
286
|
+
raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
|
287
|
+
end
|
288
|
+
|
289
|
+
when :check
|
290
|
+
args.expect(0)
|
291
|
+
program.check
|
292
|
+
|
293
|
+
when :create
|
294
|
+
cmd = opts.create!.subcommand || :release
|
295
|
+
case cmd
|
296
|
+
when :release; program.create_release(args.expect(0..1))
|
297
|
+
when :prerelease; program.create_prerelease(args.expect(0..1))
|
298
|
+
when :feature; program.create_feature(args.expect(1))
|
299
|
+
else
|
300
|
+
raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
|
301
|
+
end
|
302
|
+
|
303
|
+
when :cancel
|
304
|
+
cmd = opts.cancel!.subcommand
|
305
|
+
case cmd
|
306
|
+
when :release; program.cancel_release(args.expect(1))
|
307
|
+
when nil; raise Prick::Error, "'cancel' subcommand requires a release argument"
|
308
|
+
else
|
309
|
+
raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
|
310
|
+
end
|
311
|
+
|
312
|
+
when :generate
|
313
|
+
cmd = opts.generate!.subcommand
|
314
|
+
case cmd
|
315
|
+
when :schema; program.generate_schema
|
316
|
+
when :migration; program.generate_migration
|
317
|
+
when nil; raise Prick::Error, "'generate' subcommand requires a 'schema' or 'migration' argument"
|
318
|
+
else
|
319
|
+
raise Prick::Internal, "Subcommand #{opts.subcommand}.#{cmd} is not matched"
|
320
|
+
end
|
321
|
+
|
322
|
+
when :upgrade
|
323
|
+
args.expect(0)
|
324
|
+
program.upgrade
|
325
|
+
|
326
|
+
when :backup
|
327
|
+
program.backup(args.expect(0..1))
|
328
|
+
|
329
|
+
when :restore
|
330
|
+
program.restore(args.expect(0..1))
|
331
|
+
else
|
332
|
+
raise Prick::Internal, "Subcommand #{opts.subcommand} is not matched"
|
459
333
|
end
|
460
334
|
|
461
335
|
rescue Prick::Fail => ex # Handling of Fail has to come first because Fail < Error
|
@@ -464,4 +338,56 @@ rescue Prick::Error => ex
|
|
464
338
|
ShellOpts.error(ex.message)
|
465
339
|
end
|
466
340
|
|
341
|
+
__END__
|
467
342
|
|
343
|
+
# Awaits support for sections in ShellOpts
|
344
|
+
HELP = %(
|
345
|
+
OPTIONS
|
346
|
+
-n, --name=NAME
|
347
|
+
-C, --directory=DIR
|
348
|
+
-h, --help
|
349
|
+
-v, --verbose
|
350
|
+
--version
|
351
|
+
|
352
|
+
COMMANDS
|
353
|
+
INITIALIZATION
|
354
|
+
init --user=USER [DIR]
|
355
|
+
|
356
|
+
INFO COMMANDS
|
357
|
+
info
|
358
|
+
list releases --migrations --cancelled
|
359
|
+
list migrations
|
360
|
+
list upgrades --all
|
361
|
+
|
362
|
+
BUILDING
|
363
|
+
build -d DATABASE -C --nocache [TAG]
|
364
|
+
make -d DATABASE -C --nocache [TAG]
|
365
|
+
make clean -a
|
366
|
+
load -d DATABASE VERSION|FILE
|
367
|
+
save VERSION [FILE]
|
368
|
+
drop --all [DATABASE]
|
369
|
+
diff [FROM-DATABASE|FROM-VERSION [TO-DATABASE|TO-VERSION]]
|
370
|
+
migrate
|
371
|
+
|
372
|
+
PREPARING RELEASES
|
373
|
+
prepare release [FORK]
|
374
|
+
prepare feature NAME
|
375
|
+
prepare migration FROM
|
376
|
+
prepare schema NAME
|
377
|
+
prepare diff [VERSION]
|
378
|
+
include feature FEATURE
|
379
|
+
check
|
380
|
+
|
381
|
+
CREATING RELEASES
|
382
|
+
create release [RELEASE]
|
383
|
+
create prerelease RELEASE
|
384
|
+
create feature NAME
|
385
|
+
cancel release RELEASE
|
386
|
+
|
387
|
+
DEPLOYING RELEASES
|
388
|
+
generate migration
|
389
|
+
generate schema
|
390
|
+
upgrade
|
391
|
+
backup [FILE]
|
392
|
+
restore [FILE]
|
393
|
+
)
|