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/lib/prick/diff.rb CHANGED
@@ -1,14 +1,17 @@
1
1
  module Prick
2
+ # Database diff
2
3
  class Diff
3
4
  # Diff as a list of lines
4
5
  attr_reader :diff
5
6
 
6
- # Subject of the diff
7
+ # Diff split into before/after table changes
7
8
  attr_reader :before_table_changes
8
9
  attr_reader :table_changes
9
10
  attr_reader :after_table_changes
10
11
 
11
12
  def initialize(db1, db2)
13
+ constrain db1, String
14
+ constrain db2, String
12
15
  @db1, @db2 = db1, db2
13
16
  do_diff
14
17
  split_on_table_changes
@@ -17,40 +20,35 @@ module Prick
17
20
  def self.same?(db1, db2) Diff.new(db1, db2).same? end
18
21
 
19
22
  # Return true if the two databases are equal. Named #same? to avoid name
20
- # collision with the built in #equal?
23
+ # collision with the built-in #equal? method
21
24
  def same?() diff.empty? end
22
25
 
26
+ # :call-seq:
27
+ # write(file, mark: true)
28
+ # write(file1, file2, file3, mark: false)
29
+ #
23
30
  # Write the diff between the databases to the given file(s). Return true if
24
31
  # the databases are equal
25
- def write_segments(file1, file2 = nil, file3 = nil, mark: true)
32
+ def write(file1, file2 = nil, file3 = nil, mark: nil)
26
33
  if file2.nil? && file3.nil?
27
34
  file2 = file3 = file1
28
- elsif file2.nil? ^ !file3.nil?
29
- raise Internal, "Either none or both of `file2` and `file3` should be nil"
35
+ mark = mark.nil? ? true : mark
36
+ elsif file2.nil? != file3.nil?
37
+ raise Prick::Fail, "Either none or both of `file2` and `file3` should be nil"
38
+ else
39
+ mark = mark.nil? ? false : mark
30
40
  end
31
41
  write_segment(file1, :before_table_changes, mark: mark)
32
42
  write_segment(file2, :table_changes, mark: mark)
33
43
  write_segment(file3, :after_table_changes, mark: mark)
34
44
  end
35
45
 
36
- def write_segment(file, segment, mark: true)
37
- lines = self.send(segment)
38
- if lines.empty?
39
- FileUtils.rm_f(file) if file != "/dev/stdout"
40
- else
41
- File.open(file, "w") { |f|
42
- f.puts "--" + segment.to_s.gsub("_", " ").upcase if mark
43
- f.puts lines
44
- }
45
- end
46
- end
47
-
48
46
  private
49
47
  def do_diff(file = nil)
50
48
  command = "migra --unsafe --with-privileges postgres:///#{@db1} postgres:///#{@db2}"
51
49
  @diff = Command.command(command, fail: false)
52
50
  [0,2].include?(Command.status) or
53
- raise Internal, "migrate command failed with status #{Command.status}: #{command}"
51
+ raise Prick::Fail, "migrate command failed with status #{Command.status}: #{command}"
54
52
  end
55
53
 
56
54
  # Initialize table change variables
@@ -110,6 +108,18 @@ module Prick
110
108
  end
111
109
  }
112
110
  end
111
+
112
+ def write_segment(file, segment, mark: true)
113
+ lines = self.send(segment)
114
+ if lines.empty?
115
+ FileUtils.touch(file)
116
+ else
117
+ File.open(file, "w") { |f|
118
+ f.puts "-- " + segment.to_s.gsub("_", " ").upcase if mark
119
+ f.puts lines
120
+ }
121
+ end
122
+ end
113
123
  end
114
124
  end
115
125
 
@@ -0,0 +1,161 @@
1
+
2
+ require 'semantic' # https://github.com/jlindsey/semantic
3
+
4
+ # Project related code starts here
5
+ module Prick
6
+ class PrickVersion
7
+ class FormatError < RuntimeError; end
8
+
9
+ include Comparable
10
+
11
+ PRE_LABEL = "pre"
12
+ PRE_RE = /^#{PRE_LABEL}\.(\d+)$/
13
+
14
+ def self.zero() PrickVersion.new("0.0.0") end
15
+ def zero?() self == PrickVersion.zero end
16
+
17
+ # Return true if `string` is a version
18
+ def self.version?(string)
19
+ string.is_a?(String) or raise Internal, "String expected"
20
+ !(string =~ VERSION_RE).nil?
21
+ end
22
+
23
+ attr_accessor :fork
24
+ attr_accessor :semver
25
+ attr_accessor :feature
26
+
27
+ def major() @semver.major end
28
+ def major=(major) @semver.major = major end
29
+
30
+ def minor() @semver.minor end
31
+ def minor=(minor) @semver.minor = minor end
32
+
33
+ def patch() @semver.patch end
34
+ def patch=(patch) @semver.patch = patch end
35
+
36
+ # Return true if this is a fork release
37
+ def fork?() !@fork.nil? end
38
+
39
+ # Return true if this is a feature release
40
+ def feature?() !@feature.nil? end
41
+
42
+ # Return true if this is a release branch (and not a prerelease)
43
+ def release?() !feature? && !pre? end
44
+
45
+ # Return true if this is a pre-release
46
+ def pre?() !@semver.pre.nil? end
47
+ def prerelease?() pre? end
48
+
49
+ # The releases is stored as a String (eg. 'pre.1') in the semantic version
50
+ # but #pre returns only the Integer number
51
+ def pre() @semver.pre =~ PRE_RE ? $1.to_i : nil end
52
+ def prerelease() pre end
53
+
54
+ # #pre= expects an integer or nil argument
55
+ def pre=(pre) @semver.pre = (pre ? "#{PRE_LABEL}.#{pre}" : nil) end
56
+ def prerelease=(pre) self.pre = pre end
57
+
58
+ def dup() PrickVersion.new(self) end
59
+ def clone() PrickVersion.new(self) end
60
+
61
+ def eql?(other) self == other end
62
+ def hash() @semver.hash end
63
+
64
+ def initialize(version, fork: nil, feature: nil)
65
+ case version
66
+ when String
67
+ version =~ VERSION_RE or raise PrickVersion::FormatError, "Expected a version, got #{version.inspect}"
68
+ @fork = fork || $1
69
+ @semver = Semantic::Version.new($3)
70
+ @feature = feature || $4
71
+ when Semantic::Version
72
+ @fork = fork
73
+ @semver = version.dup
74
+ @feature = feature
75
+ when PrickVersion
76
+ @fork = fork || version.fork
77
+ @semver = version.semver.dup
78
+ @feature = feature || version.feature
79
+ else
80
+ raise Internal, "Expected a String, PrickVersion, or Semantic::Version, got #{version.class}"
81
+ end
82
+ end
83
+
84
+ # Try converting the string `version` into a PrickVersion object. Return nil if unsuccessful
85
+ def self.try(version)
86
+ version.is_a?(PrickVersion) ? version : (version?(version) ? new(version) : nil)
87
+ end
88
+
89
+ # Parse a branch or tag name into a PrickVersion object. Return a [version, tag]
90
+ # tuple where tag is true if name was a tag
91
+ def self.parse(name)
92
+ name =~ VERSION_RE or raise PrickVersion::FormatError, "Expected a version, got #{name.inspect}"
93
+ fork, tag, semver, feature = $1, $2, $3, $4
94
+ version = PrickVersion.new(semver, fork: fork, feature: feature)
95
+ [version, tag]
96
+ end
97
+
98
+ # `part` can be one of :major, :minor, :patch, or :pre. If pre is undefined, it
99
+ # is set to `pre_initial_value`
100
+ def increment(part, pre_initial_value = 1)
101
+ self.dup.increment!(part, pre_initial_value)
102
+ end
103
+
104
+ def increment!(part, pre_initial_value = 1)
105
+ if part == :pre
106
+ self.pre = (self.pre ? self.pre + 1 : pre_initial_value)
107
+ else
108
+ @semver = semver.increment!(part)
109
+ end
110
+ self
111
+ end
112
+
113
+ def truncate(part)
114
+ case part
115
+ when :pre
116
+ v = self.dup
117
+ v.feature = nil
118
+ v.pre = nil
119
+ v
120
+ when :feature
121
+ v = self.dup
122
+ v.feature = nil
123
+ v
124
+ else
125
+ raise NotYet
126
+ end
127
+ end
128
+
129
+ # def path
130
+ # parts = [FEATURE_DIR, truncate(:pre), feature].compact
131
+ # File.join(*parts)
132
+ # end
133
+
134
+ # def link
135
+ # !feature? or raise Internal, "PrickVersion #{to_s} is a feature, not a release"
136
+ # File.join(RELEASE_DIR, to_s)
137
+ # end
138
+
139
+ def <=>(other)
140
+ r = (fork || "") <=> (other.fork || "")
141
+ return r if r != 0
142
+ r = semver <=> other.semver
143
+ return r if r != 0
144
+ r = (feature || "") <=> (other.feature || "")
145
+ return r
146
+ end
147
+
148
+ # Render as branch
149
+ def to_s(tag: false)
150
+ (fork ? "#{fork}-" : "") + (tag ? "v" : "") + semver.to_s + (feature ? "_#{feature}" : "")
151
+ end
152
+
153
+ # Render as a tag
154
+ def to_tag() to_s(tag: true) end
155
+
156
+ # Render as string
157
+ def inspect() to_s end
158
+ end
159
+ end
160
+
161
+
data/lib/prick/state.rb CHANGED
@@ -2,191 +2,106 @@
2
2
  require 'yaml'
3
3
 
4
4
  module Prick
5
- # General interface for prick state files. Comments are automatically removed
6
- class PrickFile
7
- attr_reader :path
8
- def initialize(path) @path = path end
9
- def exist?() File.exist?(path) end
10
- def self.exist?() self.new.exist? end # Require an #initializer with no arguments
11
-
12
- def self.load(*args) self.new(*args).read end
13
-
14
- def self.read() raise NotThis end
15
-
16
- protected
17
- # Read file from disk or from the given branch or tag
18
- def general_read(method, branch: nil, tag: nil)
19
- !(branch && tag) or raise Internal, "Not both of `branch` and `tag` can be defined"
20
- branch || tag ? Git.send(method, path, branch: branch, tag: tag) : File.open(path, "r").send(method)
21
- end
5
+ class State
6
+ # State file
7
+ def file() PRICK_PROJECT_PATH end
22
8
 
23
- def do_read(**opts) general_read(:read, **opts) end
24
- def do_readline(**opts) do_readlines(**opts).first end
25
- def do_readlines(**opts) general_read(:readlines, **opts).reject { |l| l =~ /^\s*#/ } end
26
- end
9
+ # Schema data file
10
+ def schema_file() SCHEMA_VERSION_PATH end
27
11
 
28
- # Models the .prick-version file. It contains just one line with the version
29
- # of prick itself
30
- class PrickVersion < PrickFile
31
- def initialize() super PRICK_VERSION_FILE end
12
+ # Used as an identifier and the default database and username
13
+ attr_accessor :name
32
14
 
33
- # Return the version
34
- def read(branch: nil, tag: nil)
35
- Version.new(do_readline(branch: branch, tag: tag).chomp.sub(/^prick-/, ""))
36
- end
15
+ # Capitalized name of project
16
+ attr_accessor :title
37
17
 
38
- # Write prick version
39
- def write(version)
40
- File.open(path, "w") { |file| file.puts "prick-#{version}" }
41
- end
42
- end
18
+ # Version in prick.yml. Can be nil
19
+ attr_accessor :version
43
20
 
44
- # Models the schema version that is stored in the data.sql file in the prick
45
- # schema directory. Note that SchemaVersion caches the version. Use #clear to
46
- # reset the cache
47
- class SchemaVersion < PrickFile
48
- def initialize(version = nil)
49
- @version = version
50
- super SCHEMA_VERSION_PATH
51
- end
21
+ # Version in schema/prick/data.sql. Retrieved dynamically. TODO
22
+ attr_reader :schema_version
52
23
 
53
- def clear() @version = nil end
54
-
55
- def create() raise Internal, "This should not happen" end
56
-
57
- def read(**opts)
58
- return @version if @version
59
- lines = do_readlines
60
- while !lines.empty?
61
- line = lines.shift.chomp
62
- next if line != COPY_STMT
63
- data = lines.shift.chomp
64
- a = data.split("\t").map { |val| parse_sql_literal(val) }
65
- a.size == FIELDS.size + 1 or raise Fail, "Illegal data format in #{path}"
66
- fork, major, minor, patch, pre, feature, version = *a[1..-1]
67
- @version = Version.new("0.0.0", fork: fork, feature: feature)
68
- @version.major = major
69
- @version.minor = minor
70
- @version.patch = patch
71
- @version.pre = pre
72
- return @version
73
- end
74
- raise Fail, "No COPY statement in #{path}"
75
- end
24
+ # Version from prick.versions.version. Retrieved dynamically. TODO FIXME: Where is conn?
25
+ attr_reader :database_version
76
26
 
77
- def write(version = @version)
78
- # puts "Writing #{path}"
79
- version_string = version.truncate(:pre).to_s
80
- File.open(path, "w") { |f|
81
- f.puts "--"
82
- f.puts "-- This file is auto-generated by prick(1). Please don't touch"
83
- f.puts COPY_STMT
84
- f.print \
85
- "1\t",
86
- FIELDS[..-2].map { |f| version.send(f.to_sym) || '\N' }.join("\t"),
87
- "\t#{version_string}\n"
88
- f.puts "\\."
89
- }
90
- Git.add(path)
91
- version
92
- end
27
+ # Version of prick(1)
28
+ attr_accessor :prick_version
93
29
 
94
- private
95
- FIELDS = %w(fork major minor patch pre feature version)
96
- COPY_STMT = "COPY prick.versions (id, #{FIELDS.join(', ')}) FROM stdin;"
30
+ # Run-time environment. Can be :production, :development, or :test
31
+ attr_accessor :environment
97
32
 
98
- def parse_sql_literal(s)
99
- case s
100
- when '\N', 'null'; nil
101
- when/^\d+$/; s.to_i
102
- else
103
- s
104
- end
105
- end
106
- end
107
-
108
- # General interface for prick state files in YAML format
109
- class State < PrickFile
110
- # `fields` is a Hash from field name (Symbol) to field type (class) where a
111
- # class can be a class known to YAML (Integer, String, etc.) or Version.
112
- # The #initialize method generates an accessor methods for each field
113
- def initialize(path, **fields)
114
- super(path)
115
- @fields = fields
116
- @fields.each_key { |k| self.class.attr_accessor k }
117
- @loaded = false
118
- end
33
+ # Name of database
34
+ attr_accessor :database
119
35
 
120
- def create() write end
36
+ # Name of database user
37
+ attr_accessor :username
121
38
 
122
- def set(**fields)
123
- for field, value in fields
124
- self.send(:"#{field}=", value)
39
+ def self.load
40
+ begin
41
+ h = YAML.load(File.read PRICK_PROJECT_PATH)
42
+ rescue Errno::ENOENT
43
+ raise Prick::Error, "Can't open project file: #{PRICK_PROJECT_PATH}"
125
44
  end
126
- self
127
- end
128
-
129
- def read(branch: nil, tag: nil)
130
- return self if @loaded
131
- hash = YAML.load(do_read(branch: branch, tag: tag))
132
- for field, klass in @fields
133
- value = hash[field.to_s]
134
- value = Version.new(value) if klass == Version && !value.nil?
135
- self.instance_variable_set("@#{field}", value)
45
+ state = State.new
46
+ state.name = h["name"]
47
+ state.title = h["title"]
48
+ state.version = h["version"] && PrickVersion.new(h["version"])
49
+ state.prick_version = h["prick"] && PrickVersion.new(h["prick"])
50
+
51
+ begin
52
+ h = YAML.load(File.read PRICK_CONTEXT_PATH)
53
+ rescue Errno::ENOENT
54
+ raise Prick::Error, "Can't open environment file: #{PRICK_CONTEXT_PATH}"
136
55
  end
137
- @loaded = true
138
- self
139
- end
56
+ state.environment = h["environment"]&.to_sym
57
+ state.database = h["database"]
58
+ state.username = h["username"]
140
59
 
141
- def write(**fields)
142
- set(**fields)
143
- hash = @fields.map { |field, klass|
144
- value = self.send(field)
145
- value = value.to_s if klass == Version && !value.nil?
146
- [field.to_s, value]
147
- }.to_h
148
- IO.write(@path, YAML.dump(hash))
149
- raise if @version.is_a?(Array)
150
- self
151
- end
152
- end
60
+ # TODO Load schema version
153
61
 
154
- class MigrationState < State
155
- def initialize(version: nil, base_version: nil)
156
- super(PRICK_MIGRATION_PATH, version: Version, base_version: Version)
157
- set(version: version, base_version: base_version)
62
+ state
158
63
  end
159
- end
160
64
 
161
- class HeadState < State
162
- def initialize(name: nil)
163
- super(PRICK_HEAD_PATH, name: String)
164
- set(name: name)
165
- end
166
- end
65
+ def save
66
+ h = {
67
+ "name" => name,
68
+ "title" => title,
69
+ "version" => version.to_s,
70
+ "prick" => prick_version.to_s
71
+ }
72
+ File.write(PRICK_PROJECT_PATH, h.to_yaml)
167
73
 
168
- class FeatureState < State
169
- def initialize(feature: nil)
170
- super(PRICK_FEATURE_PATH, feature: String)
171
- set(feature: feature)
74
+ h = {
75
+ "environment" => environment.to_s,
76
+ "database" => database,
77
+ "username" => username
78
+ }
79
+ File.write(PRICK_CONTEXT_PATH, h.to_yaml)
80
+
81
+ if version
82
+ File.write(SCHEMA_VERSION_PATH,
83
+ <<~EOS
84
+ --
85
+ -- This file is auto-generated by prick(1). Please don't touch
86
+ --
87
+ delete from prick.versions;
88
+ insert into prick.versions (fork, major, minor, patch, pre, feature, version)
89
+ values (null, #{version.major}, #{version.minor}, #{version.patch}, null, null, '#{version}');
90
+ EOS
91
+ )
92
+ end
172
93
  end
173
- end
174
94
 
175
- # class FeaturesState < State
176
- # def initialize(directory, features: [])
177
- # super(File.join(directory, FEATURES_STATE_FILE), features: Array)
178
- # set(features: features)
179
- # end
180
- # end
181
- #
182
-
183
- # Models the .prick-project file that contains the name of the project and
184
- # the database user
185
- class ProjectState < State
186
- def initialize(name: nil, user: nil)
187
- super(PROJECT_STATE_FILE, name: String, user: String)
188
- set(name: name, user: user)
95
+ def dump
96
+ puts "State"
97
+ indent {
98
+ for method in [
99
+ :name, :title, :prick_version, :project_version, :schema_version,
100
+ :database_version, :environment, :database, :username]
101
+ puts "#{method}: #{self.send method}"
102
+ end
103
+ }
189
104
  end
190
105
  end
191
-
192
106
  end
107
+
data/lib/prick/version.rb CHANGED
@@ -1,166 +1,5 @@
1
+ # frozen_string_literal: true
1
2
 
2
- # "require 'semantic'" is moved to lib/prick.rb to avoid having Gem depend on it
3
- # require 'semantic' # https://github.com/jlindsey/semantic
4
-
5
- # Required by gem
6
3
  module Prick
7
- VERSION = "0.18.0"
4
+ VERSION = "0.20.2"
8
5
  end
9
-
10
- # Project related code starts here
11
- module Prick
12
- class Version
13
- class FormatError < RuntimeError; end
14
-
15
- include Comparable
16
-
17
- PRE_LABEL = "pre"
18
- PRE_RE = /^#{PRE_LABEL}\.(\d+)$/
19
-
20
- def self.zero() Version.new("0.0.0") end
21
- def zero?() self == Version.zero end
22
-
23
- # Return true if `string` is a version
24
- def self.version?(string)
25
- string.is_a?(String) or raise Internal, "String expected"
26
- !(string =~ VERSION_RE).nil?
27
- end
28
-
29
- attr_accessor :fork
30
- attr_accessor :semver
31
- attr_accessor :feature
32
-
33
- def major() @semver.major end
34
- def major=(major) @semver.major = major end
35
-
36
- def minor() @semver.minor end
37
- def minor=(minor) @semver.minor = minor end
38
-
39
- def patch() @semver.patch end
40
- def patch=(patch) @semver.patch = patch end
41
-
42
- # Return true if this is a fork release
43
- def fork?() !@fork.nil? end
44
-
45
- # Return true if this is a feature release
46
- def feature?() !@feature.nil? end
47
-
48
- # Return true if this is a release branch (and not a prerelease)
49
- def release?() !feature? && !pre? end
50
-
51
- # Return true if this is a pre-release
52
- def pre?() !@semver.pre.nil? end
53
- def prerelease?() pre? end
54
-
55
- # The releases is stored as a String (eg. 'pre.1') in the semantic version
56
- # but #pre returns only the Integer number
57
- def pre() @semver.pre =~ PRE_RE ? $1.to_i : nil end
58
- def prerelease() pre end
59
-
60
- # #pre= expects an integer or nil argument
61
- def pre=(pre) @semver.pre = (pre ? "#{PRE_LABEL}.#{pre}" : nil) end
62
- def prerelease=(pre) self.pre = pre end
63
-
64
- def dup() Version.new(self) end
65
- def clone() Version.new(self) end
66
-
67
- def eql?(other) self == other end
68
- def hash() @semver.hash end
69
-
70
- def initialize(version, fork: nil, feature: nil)
71
- case version
72
- when String
73
- version =~ VERSION_RE or raise Version::FormatError, "Expected a version, got #{version.inspect}"
74
- @fork = fork || $1
75
- @semver = Semantic::Version.new($3)
76
- @feature = feature || $4
77
- when Semantic::Version
78
- @fork = fork
79
- @semver = version.dup
80
- @feature = feature
81
- when Version
82
- @fork = fork || version.fork
83
- @semver = version.semver.dup
84
- @feature = feature || version.feature
85
- else
86
- raise Internal, "Expected a String, Version, or Semantic::Version, got #{version.class}"
87
- end
88
- end
89
-
90
- # Try converting the string `version` into a Version object. Return nil if unsuccessful
91
- def self.try(version)
92
- version.is_a?(Version) ? version : (version?(version) ? new(version) : nil)
93
- end
94
-
95
- # Parse a branch or tag name into a Version object. Return a [version, tag]
96
- # tuple where tag is true if name was a tag
97
- def self.parse(name)
98
- name =~ VERSION_RE or raise Version::FormatError, "Expected a version, got #{version.inspect}"
99
- fork, tag, semver, feature = $1, $2, $3, $4
100
- version = Version.new(semver, fork: fork, feature: feature)
101
- [version, tag]
102
- end
103
- # `part` can be one of :major, :minor, :patch, or :pre. If pre is undefined, it
104
- # is set to `pre_initial_value`
105
- def increment(part, pre_initial_value = 1)
106
- self.dup.increment!(part, pre_initial_value)
107
- end
108
-
109
- def increment!(part, pre_initial_value = 1)
110
- if part == :pre
111
- self.pre = (self.pre ? self.pre + 1 : pre_initial_value)
112
- else
113
- @semver = semver.increment!(part)
114
- end
115
- self
116
- end
117
-
118
- def truncate(part)
119
- case part
120
- when :pre
121
- v = self.dup
122
- v.feature = nil
123
- v.pre = nil
124
- v
125
- when :feature
126
- v = self.dup
127
- v.feature = nil
128
- v
129
- else
130
- raise NotYet
131
- end
132
- end
133
-
134
- # def path
135
- # parts = [FEATURE_DIR, truncate(:pre), feature].compact
136
- # File.join(*parts)
137
- # end
138
-
139
- # def link
140
- # !feature? or raise Internal, "Version #{to_s} is a feature, not a release"
141
- # File.join(RELEASE_DIR, to_s)
142
- # end
143
-
144
- def <=>(other)
145
- r = (fork || "") <=> (other.fork || "")
146
- return r if r != 0
147
- r = semver <=> other.semver
148
- return r if r != 0
149
- r = (feature || "") <=> (other.feature || "")
150
- return r
151
- end
152
-
153
- # Render as branch
154
- def to_s(tag: false)
155
- (fork ? "#{fork}-" : "") + (tag ? "v" : "") + semver.to_s + (feature ? "_#{feature}" : "")
156
- end
157
-
158
- # Render as a tag
159
- def to_tag() to_s(tag: true) end
160
-
161
- # Render as string
162
- def inspect() to_s end
163
- end
164
- end
165
-
166
-