static_db 0.0.5 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20d2161d54e8efc24b529deb87f934c9396a75f2943598a72ce3b9b6f71cd265
4
- data.tar.gz: ca21c07aa5f2dfa151e683719c5de3f9aff57f8ef8bdd729618718b30d301623
3
+ metadata.gz: 21a5a8909bd4d182d4045ce780e15d9d33c2a2e226148e76928ef76391b6c465
4
+ data.tar.gz: 901c8f63945110038f237f562150106d167c2eb6033ec17cf82e60eda97df89a
5
5
  SHA512:
6
- metadata.gz: 129469328ab921155e7ff25c5cdca998cb6587febdec05bbe36939473ef2431189e5d5ea46e188638335f8d909a6b7c7739ceb1ed32ea881faf65ce816a7370b
7
- data.tar.gz: 4dec7f69183acab466df33e7ff24d686054472238f6294935afd780d32e6b103fd02d54f543ac9917604c0426775d3e519d81bdd09f57217f8f003a048d4f904
6
+ metadata.gz: 6ff8c6ac84a7a469918dfe1781b4aa94fee65fb81a7bda3f858f11e5be4b7681da9913d7e502bcf8f25270f1f7bf60fdda5a95a8b93a9d861a1eb17bd0dbf8c4
7
+ data.tar.gz: befb42dbc227cac64482b9dfcd966c0f0f53754ccb3d71eff0893791c2fe3889f544c674d45a4c97c563026196e6ff2c9da28f2ceb1611bc72fb9afca79362b0
data/CHANGELOG.md CHANGED
@@ -1,13 +1,31 @@
1
1
  # Changelog
2
2
 
3
- > :warning: This project is not inteded for public usage yet.
4
-
5
- I will start keeping a changelog as soon as that happens.
6
-
7
3
  This project adheres to [Break Versioning](https://www.taoensso.com/break-versioning).
8
4
 
9
5
  ## [Unreleased]
10
6
 
11
7
  ### Breaking
12
8
 
9
+ -
10
+
13
11
  ### Non-breaking
12
+
13
+ -
14
+
15
+ ## [0.1.0] - 2026-05-03
16
+
17
+ ### Breaking
18
+
19
+ - Drop database at a different point in time now. It's possible, but unlikely that this breaks anything for you.
20
+ - Previously: `db:drop` happend after dumping out data on shutdown.
21
+ - If dumping data failed, your `.sqlite3` files would remain and the next boot would fail.
22
+ - If everything succeeded, it worked OK, but keeping the `.sqlite3` files around might still be beneficial.
23
+ - Now: `db:drop` happens before loading data on boot.
24
+ - After a failed shutdown (e.g. due to validation errors), you don't need to manually delete the files anymore.
25
+ Restarting your Rails servers discards all data changes.
26
+ - After an interrupted shutdown (e.g. `bin/dev` / `foreman` killing your Rails process too early) you can
27
+ now retry dumping data via `bin/rails static:dump`.
28
+
29
+ ### Non-breaking
30
+
31
+ - Internal code cleanup
data/README.md CHANGED
@@ -7,14 +7,16 @@ Dump DB contents to YAML and load them back again. Aimed at SQLite. Committable
7
7
 
8
8
  ## Installation
9
9
 
10
- WARNING: This gem modifies the Rails startup sequence. Don't use this gem unless you want to build a static site generator. This gem also creates and drops the DB for you.
10
+ > ⚠️ This gem modifies the Rails startup sequence. Don't use this gem unless you want to build a static site generator. This gem also creates and drops the DB for you.
11
11
 
12
12
  Add it to your Rails project:
13
13
 
14
14
  ```ruby
15
15
  # Gemfile
16
16
  gem "static_db"
17
+ ```
17
18
 
19
+ ```ruby
18
20
  # config/initializer/static_db.rb
19
21
  StaticDb.configure do |config|
20
22
  # `content/data` is the default. You only need this initializer,
@@ -25,15 +27,15 @@ end
25
27
 
26
28
  ## Usage
27
29
 
28
- Only use on Rails projects with SQLite. Have a valid `db/schema.rb`. For additional dramatic effect, do a `rails db:drop`.
30
+ > ⚠️ Only use on Rails projects with SQLite. Have a valid `db/schema.rb`.
29
31
 
30
32
  Start your app with `bin/dev`. You will notice that a DB gets created for you. It will be empty.
31
33
 
32
34
  Create some records. Then, stop your server with Ctrl+C.
33
35
 
34
- The DB contents will have been dumped to `content/data`. Your SQLite DB will be gone.
36
+ The DB contents will have been dumped to `content/data`.
35
37
 
36
- Restart your server with `bin/dev`. Your SQLite DB will be back and populated with all previously stored data, recreated from `content/data`.
38
+ Restart your server with `bin/dev`. Your SQLite DB will be dropped and recreated with all previously stored data from `content/data`.
37
39
 
38
40
  ## Contributing
39
41
 
@@ -0,0 +1,189 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copied and inlined from Rails, as it was deprecated there.
4
+
5
+ require "active_support/concern"
6
+ require "active_support/ordered_options"
7
+
8
+ module StaticDb
9
+ # = Active Support \Configurable
10
+ #
11
+ # Configurable provides a <tt>config</tt> method to store and retrieve
12
+ # configuration options as an OrderedOptions.
13
+ module Configurable
14
+ extend ActiveSupport::Concern
15
+
16
+ class Configuration < ActiveSupport::InheritableOptions
17
+ def compile_methods!
18
+ self.class.compile_methods!(keys)
19
+ end
20
+
21
+ # Compiles reader methods so we don't have to go through method_missing.
22
+ def self.compile_methods!(keys)
23
+ keys.reject { |m| method_defined?(m) }.each do |key|
24
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
25
+ def #{key}; _get(#{key.inspect}); end
26
+ RUBY
27
+ end
28
+ end
29
+ end
30
+
31
+ module ClassMethods
32
+ # Reads and writes attributes from a configuration OrderedOptions.
33
+ #
34
+ # require "active_support/configurable"
35
+ #
36
+ # class User
37
+ # include ActiveSupport::Configurable
38
+ # end
39
+ #
40
+ # User.config.allowed_access = true
41
+ # User.config.level = 1
42
+ #
43
+ # User.config.allowed_access # => true
44
+ # User.config.level # => 1
45
+ def config
46
+ @_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config)
47
+ superclass.config.inheritable_copy
48
+ else
49
+ # create a new "anonymous" class that will host the compiled reader methods
50
+ Class.new(Configuration).new
51
+ end
52
+ end
53
+
54
+ # Configure values from within the passed block.
55
+ #
56
+ # require "active_support/configurable"
57
+ #
58
+ # class User
59
+ # include ActiveSupport::Configurable
60
+ # end
61
+ #
62
+ # User.allowed_access # => nil
63
+ #
64
+ # User.configure do |config|
65
+ # config.allowed_access = true
66
+ # end
67
+ #
68
+ # User.allowed_access # => true
69
+ def configure
70
+ yield config
71
+ end
72
+
73
+ # Allows you to add shortcut so that you don't have to refer to attribute
74
+ # through config. Also look at the example for config to contrast.
75
+ #
76
+ # Defines both class and instance config accessors.
77
+ #
78
+ # class User
79
+ # include ActiveSupport::Configurable
80
+ # config_accessor :allowed_access
81
+ # end
82
+ #
83
+ # User.allowed_access # => nil
84
+ # User.allowed_access = false
85
+ # User.allowed_access # => false
86
+ #
87
+ # user = User.new
88
+ # user.allowed_access # => false
89
+ # user.allowed_access = true
90
+ # user.allowed_access # => true
91
+ #
92
+ # User.allowed_access # => false
93
+ #
94
+ # The attribute name must be a valid method name in Ruby.
95
+ #
96
+ # class User
97
+ # include ActiveSupport::Configurable
98
+ # config_accessor :"1_Badname"
99
+ # end
100
+ # # => NameError: invalid config attribute name
101
+ #
102
+ # To omit the instance writer method, pass <tt>instance_writer: false</tt>.
103
+ # To omit the instance reader method, pass <tt>instance_reader: false</tt>.
104
+ #
105
+ # class User
106
+ # include ActiveSupport::Configurable
107
+ # config_accessor :allowed_access, instance_reader: false, instance_writer: false
108
+ # end
109
+ #
110
+ # User.allowed_access = false
111
+ # User.allowed_access # => false
112
+ #
113
+ # User.new.allowed_access = true # => NoMethodError
114
+ # User.new.allowed_access # => NoMethodError
115
+ #
116
+ # Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
117
+ #
118
+ # class User
119
+ # include ActiveSupport::Configurable
120
+ # config_accessor :allowed_access, instance_accessor: false
121
+ # end
122
+ #
123
+ # User.allowed_access = false
124
+ # User.allowed_access # => false
125
+ #
126
+ # User.new.allowed_access = true # => NoMethodError
127
+ # User.new.allowed_access # => NoMethodError
128
+ #
129
+ # Also you can pass <tt>default</tt> or a block to set up the attribute with a default value.
130
+ #
131
+ # class User
132
+ # include ActiveSupport::Configurable
133
+ # config_accessor :allowed_access, default: false
134
+ # config_accessor :hair_colors do
135
+ # [:brown, :black, :blonde, :red]
136
+ # end
137
+ # end
138
+ #
139
+ # User.allowed_access # => false
140
+ # User.hair_colors # => [:brown, :black, :blonde, :red]
141
+ def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) # :doc:
142
+ names.each do |name|
143
+ raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
144
+
145
+ reader, reader_line = "def #{name}; config.#{name}; end", __LINE__
146
+ writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__
147
+
148
+ singleton_class.class_eval reader, __FILE__, reader_line
149
+ singleton_class.class_eval writer, __FILE__, writer_line
150
+
151
+ if instance_accessor
152
+ class_eval reader, __FILE__, reader_line if instance_reader
153
+ class_eval writer, __FILE__, writer_line if instance_writer
154
+ end
155
+
156
+ send("#{name}=", block_given? ? yield : default)
157
+ end
158
+ end
159
+ private :config_accessor
160
+
161
+ private
162
+ def inherited(subclass)
163
+ super
164
+ subclass.class_eval do
165
+ @_config = nil
166
+ end
167
+ end
168
+ end
169
+
170
+ # Reads and writes attributes from a configuration OrderedOptions.
171
+ #
172
+ # require "active_support/configurable"
173
+ #
174
+ # class User
175
+ # include ActiveSupport::Configurable
176
+ # end
177
+ #
178
+ # user = User.new
179
+ #
180
+ # user.config.allowed_access = true
181
+ # user.config.level = 1
182
+ #
183
+ # user.config.allowed_access # => true
184
+ # user.config.level # => 1
185
+ def config
186
+ @_config ||= self.class.config.inheritable_copy
187
+ end
188
+ end
189
+ end
@@ -3,7 +3,7 @@ module StaticDb
3
3
 
4
4
  attr_reader :fixture_path, :models_to_be_saved
5
5
 
6
- def initialize(fixture_path:)
6
+ def initialize(fixture_path: StaticDb.config.fixture_path)
7
7
  @fixture_path = Pathname.new(fixture_path)
8
8
  @models_to_be_saved = models
9
9
  end
@@ -11,25 +11,15 @@ module StaticDb
11
11
  def perform
12
12
  exit 1 if $skip_active_fixtures_dump
13
13
 
14
- reenable_rake_tasks!
15
14
  validate_records!
16
15
 
17
16
  puts green("Dumping fixtures ...")
18
-
19
17
  dump_fixtures!
20
- Rake::Task["db:drop"].invoke
21
-
22
18
  puts green("Done!")
23
19
  end
24
20
 
25
21
  private
26
22
 
27
- def reenable_rake_tasks!
28
- ["db:drop"].each do |task_name|
29
- Rake::Task[task_name].reenable
30
- end
31
- end
32
-
33
23
  def validate_records!
34
24
  puts green("Validating records ...")
35
25
 
@@ -91,7 +81,7 @@ module StaticDb
91
81
  attrs[column.name] = value unless value.nil?
92
82
  end
93
83
 
94
- output["#{model}_#{model.id}"] = attrs
84
+ output["#{model}_#{instance.id}"] = attrs
95
85
  end
96
86
 
97
87
  output
@@ -1,6 +1,18 @@
1
- require "static_db/initializer"
1
+ require "static_db/configurable"
2
2
 
3
3
  module StaticDb # :nodoc:
4
+ # Engines are required very early in the Rails boot sequence via
5
+ # `Bundler.require(*Rails.groups)` in `application.rb`.
6
+
7
+ # Thus, the config is available before:
8
+ # - the rest of `application.rb`
9
+ # - `environment/*.rb`
10
+ # - the engines `initializer` block gets executed
11
+ # - regular initializers from `config/initializers/`
12
+ include StaticDb::Configurable
13
+
14
+ config_accessor :fixture_path, instance_accessor: false, default: -> { Rails.root.join("content", "data") }
15
+
4
16
  class Engine < ::Rails::Engine # :nodoc:
5
17
  isolate_namespace StaticDb
6
18
 
@@ -11,19 +23,11 @@ module StaticDb # :nodoc:
11
23
  initializer "static_db.configure" do |app|
12
24
  if defined?(Rails::Server) || defined?(Rails::Console) || ARGV.first == "build"
13
25
  Rails.application.config.after_initialize do
14
- unless Object.const_defined?("Rake::Task") && Rake::Task.task_defined?("static:load")
15
- Rails.application.load_tasks
16
- end
17
-
18
- Rake::Task["static:load"].invoke
26
+ StaticDb::Load.new.perform
19
27
  end
20
28
 
21
29
  at_exit do
22
- unless Object.const_defined?("Rake::Task") && Rake::Task.task_defined?("static:dump")
23
- Rails.application.load_tasks
24
- end
25
-
26
- Rake::Task["static:dump"].invoke
30
+ StaticDb::Dump.new.perform
27
31
  end
28
32
  end
29
33
  end
@@ -3,18 +3,14 @@ module StaticDb
3
3
 
4
4
  attr_reader :fixture_path
5
5
 
6
- def initialize(fixture_path:)
6
+ def initialize(fixture_path: StaticDb.config.fixture_path)
7
7
  @fixture_path = Pathname.new(fixture_path)
8
8
  end
9
9
 
10
10
  def perform
11
11
  puts green("Loading fixtures ...")
12
-
13
- reenable_rake_tasks!
14
- Rake::Task["db:create"].invoke
15
- Rake::Task["db:schema:load"].invoke
12
+ system("bin/rails", "db:drop", "db:create", "db:schema:load")
16
13
  load_fixtures!
17
-
18
14
  puts green("Done!")
19
15
  rescue => e
20
16
  puts red("Failed to load fixtures: #{e.message}")
@@ -25,12 +21,6 @@ module StaticDb
25
21
 
26
22
  private
27
23
 
28
- def reenable_rake_tasks!
29
- ["db:create", "db:schema:load"].each do |task_name|
30
- Rake::Task[task_name].reenable
31
- end
32
- end
33
-
34
24
  def load_fixtures!
35
25
  base_names = Dir.glob(File.join(fixture_path, "*.yml")).map do |file|
36
26
  File.basename(file, ".*")
@@ -1,23 +1,19 @@
1
1
  namespace :static do
2
2
  desc "Create fixtures from database; accepts optional path argument"
3
3
  task :dump, [:path] => :environment do |t, args|
4
- path = if args[:path].blank?
5
- StaticDb.config.fixture_path
4
+ if args[:path].blank?
5
+ StaticDb::Dump.new.perform
6
6
  else
7
- Rails.root.join(args[:path])
7
+ StaticDb::Dump.new(fixture_path: Rails.root.join(args[:path])).perform
8
8
  end
9
-
10
- StaticDb::Dump.new(fixture_path: path).perform
11
9
  end
12
10
 
13
11
  desc "Create database from fixtures; accepts optional path argument"
14
12
  task :load, [:path] => :environment do |t, args|
15
- path = if args[:path].blank?
16
- StaticDb.config.fixture_path
13
+ if args[:path].blank?
14
+ StaticDb::Load.new.perform
17
15
  else
18
- Rails.root.join(args[:path])
16
+ StaticDb::Load.new(fixture_path: Rails.root.join(args[:path])).perform
19
17
  end
20
-
21
- StaticDb::Load.new(fixture_path: path).perform
22
18
  end
23
19
  end
@@ -1,3 +1,3 @@
1
1
  module StaticDb # :nodoc:
2
- VERSION = "0.0.5"
2
+ VERSION = "0.1.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: static_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Klaus Weidinger
@@ -50,9 +50,9 @@ files:
50
50
  - README.md
51
51
  - Rakefile
52
52
  - lib/static_db.rb
53
+ - lib/static_db/configurable.rb
53
54
  - lib/static_db/dump.rb
54
55
  - lib/static_db/engine.rb
55
- - lib/static_db/initializer.rb
56
56
  - lib/static_db/load.rb
57
57
  - lib/static_db/tasks/static.rake
58
58
  - lib/static_db/version.rb
@@ -66,6 +66,9 @@ metadata:
66
66
  bug_tracker_uri: https://github.com/dunkelziffer/static_db/issues
67
67
  documentation_uri: https://github.com/dunkelziffer/static_db/blob/main/README.md
68
68
  rubygems_mfa_required: 'true'
69
+ post_install_message: "⚠️ This gem modifies the Rails startup sequence. Don't use
70
+ this gem unless you want to build a static site generator. This gem also creates
71
+ and drops the DB for you."
69
72
  rdoc_options: []
70
73
  require_paths:
71
74
  - lib
@@ -1,33 +0,0 @@
1
- require "ostruct"
2
-
3
- module StaticDb
4
- # Configuration and setup utility. The engine automatically requires this
5
- # file during Rails initialization, so applications can simply call
6
- # `StaticDb.configure` from **any** initializer (or even the engine's own
7
- # initializer). It behaves exactly like an initializer placed in
8
- # `config/initializers` of a Rails project.
9
- #
10
- # Example usage from a host application:
11
- #
12
- # # config/initializers/static_db.rb
13
- # StaticDb.configure do |config|
14
- # config.dump_path = Rails.root.join("content", "data")
15
- # #
16
- # # The rake tasks also accept an explicit path argument which is passed to
17
- # # the `StaticDb::Dump`/`Load` constructors; the configuration value is
18
- # # used when the argument is omitted.
19
- # end
20
- #
21
- # The configuration object is a plain OpenStruct and may be extended by
22
- # the application or other libraries.
23
- def self.configure
24
- @config ||= OpenStruct.new
25
- yield @config if block_given?
26
- @config.fixture_path ||= Rails.root.join("content", "data")
27
- @config
28
- end
29
-
30
- def self.config
31
- @config || configure
32
- end
33
- end