textus 0.5.0 → 0.8.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/CHANGELOG.md +83 -1
- data/README.md +29 -21
- data/SPEC.md +75 -142
- data/docs/architecture.md +42 -23
- data/lib/textus/builder/pipeline.rb +56 -0
- data/lib/textus/builder/renderer/json.rb +42 -0
- data/lib/textus/builder/renderer/markdown.rb +22 -0
- data/lib/textus/builder/renderer/text.rb +14 -0
- data/lib/textus/builder/renderer/yaml.rb +42 -0
- data/lib/textus/builder/renderer.rb +17 -0
- data/lib/textus/builder.rb +9 -114
- data/lib/textus/cli/group/hook.rb +11 -0
- data/lib/textus/cli/group/key.rb +12 -0
- data/lib/textus/cli/group/schema.rb +13 -0
- data/lib/textus/cli/verb/accept.rb +15 -0
- data/lib/textus/cli/verb/build.rb +13 -0
- data/lib/textus/cli/verb/delete.rb +16 -0
- data/lib/textus/cli/verb/deps.rb +12 -0
- data/lib/textus/cli/verb/doctor.rb +15 -0
- data/lib/textus/cli/verb/get.rb +12 -0
- data/lib/textus/cli/verb/hook_run.rb +48 -0
- data/lib/textus/cli/verb/hooks.rb +50 -0
- data/lib/textus/cli/verb/init.rb +14 -0
- data/lib/textus/cli/verb/intro.rb +11 -0
- data/lib/textus/cli/verb/list.rb +14 -0
- data/lib/textus/cli/verb/migrate_keys.rb +16 -0
- data/lib/textus/cli/verb/mv.rb +17 -0
- data/lib/textus/cli/verb/published.rb +11 -0
- data/lib/textus/cli/verb/put.rb +50 -0
- data/lib/textus/cli/verb/rdeps.rb +12 -0
- data/lib/textus/cli/verb/refresh.rb +15 -0
- data/lib/textus/cli/verb/schema.rb +12 -0
- data/lib/textus/cli/verb/schema_diff.rb +12 -0
- data/lib/textus/cli/verb/schema_init.rb +16 -0
- data/lib/textus/cli/verb/schema_migrate.rb +16 -0
- data/lib/textus/cli/verb/stale.rb +14 -0
- data/lib/textus/cli/verb/uid.rb +12 -0
- data/lib/textus/cli/verb/where.rb +12 -0
- data/lib/textus/cli.rb +23 -42
- data/lib/textus/doctor/check/audit_log.rb +50 -0
- data/lib/textus/doctor/check/hooks.rb +29 -0
- data/lib/textus/doctor/check/illegal_keys.rb +49 -0
- data/lib/textus/doctor/check/manifest_files.rb +38 -0
- data/lib/textus/doctor/check/schema_violations.rb +22 -0
- data/lib/textus/doctor/check/schemas.rb +26 -0
- data/lib/textus/doctor/check/sentinels.rb +57 -0
- data/lib/textus/doctor/check/templates.rb +26 -0
- data/lib/textus/doctor/check/unowned_schema_fields.rb +34 -0
- data/lib/textus/doctor/check.rb +30 -0
- data/lib/textus/doctor.rb +22 -288
- data/lib/textus/entry/base.rb +30 -0
- data/lib/textus/entry/json.rb +5 -1
- data/lib/textus/entry/markdown.rb +1 -1
- data/lib/textus/entry/text.rb +1 -1
- data/lib/textus/entry/yaml.rb +5 -1
- data/lib/textus/entry.rb +0 -5
- data/lib/textus/envelope.rb +30 -0
- data/lib/textus/hooks/builtin.rb +70 -0
- data/lib/textus/hooks/dispatcher.rb +49 -0
- data/lib/textus/hooks/loader.rb +26 -0
- data/lib/textus/hooks/registry.rb +73 -0
- data/lib/textus/init.rb +13 -10
- data/lib/textus/intro.rb +14 -16
- data/lib/textus/key/distance.rb +55 -0
- data/lib/textus/key/grammar.rb +33 -0
- data/lib/textus/key/path.rb +17 -0
- data/lib/textus/manifest/entry.rb +199 -0
- data/lib/textus/manifest.rb +10 -34
- data/lib/textus/migrate_keys.rb +1 -1
- data/lib/textus/projection.rb +5 -4
- data/lib/textus/proposal.rb +1 -1
- data/lib/textus/refresh.rb +11 -11
- data/lib/textus/schema/tools.rb +89 -0
- data/lib/textus/store/audit_log.rb +71 -0
- data/lib/textus/store/mover.rb +19 -16
- data/lib/textus/store/reader.rb +67 -0
- data/lib/textus/store/staleness.rb +10 -19
- data/lib/textus/store/validator.rb +11 -8
- data/lib/textus/store/view.rb +29 -0
- data/lib/textus/store/writer.rb +132 -0
- data/lib/textus/store.rb +25 -221
- data/lib/textus/version.rb +1 -1
- data/lib/textus.rb +14 -67
- metadata +73 -40
- data/lib/textus/audit_log.rb +0 -67
- data/lib/textus/builtin_actions.rb +0 -68
- data/lib/textus/cli/accept.rb +0 -13
- data/lib/textus/cli/action.rb +0 -51
- data/lib/textus/cli/build.rb +0 -11
- data/lib/textus/cli/delete.rb +0 -14
- data/lib/textus/cli/deprecated_alias.rb +0 -31
- data/lib/textus/cli/deps.rb +0 -10
- data/lib/textus/cli/doctor.rb +0 -13
- data/lib/textus/cli/extension_group.rb +0 -9
- data/lib/textus/cli/extensions.rb +0 -49
- data/lib/textus/cli/get.rb +0 -10
- data/lib/textus/cli/init.rb +0 -12
- data/lib/textus/cli/intro.rb +0 -9
- data/lib/textus/cli/key_group.rb +0 -10
- data/lib/textus/cli/list.rb +0 -12
- data/lib/textus/cli/migrate.rb +0 -41
- data/lib/textus/cli/migrate_keys.rb +0 -19
- data/lib/textus/cli/mv.rb +0 -20
- data/lib/textus/cli/published.rb +0 -9
- data/lib/textus/cli/put.rb +0 -48
- data/lib/textus/cli/rdeps.rb +0 -10
- data/lib/textus/cli/refresh.rb +0 -13
- data/lib/textus/cli/schema.rb +0 -10
- data/lib/textus/cli/schema_diff.rb +0 -15
- data/lib/textus/cli/schema_group.rb +0 -33
- data/lib/textus/cli/schema_init.rb +0 -19
- data/lib/textus/cli/schema_migrate.rb +0 -19
- data/lib/textus/cli/stale.rb +0 -12
- data/lib/textus/cli/uid.rb +0 -15
- data/lib/textus/cli/where.rb +0 -10
- data/lib/textus/extension_registry.rb +0 -61
- data/lib/textus/extensions.rb +0 -33
- data/lib/textus/key_distance.rb +0 -53
- data/lib/textus/manifest_entry.rb +0 -185
- data/lib/textus/migrate_v2.rb +0 -27
- data/lib/textus/schema_tools.rb +0 -87
- data/lib/textus/store/events.rb +0 -31
- data/lib/textus/store_view.rb +0 -27
data/lib/textus/cli/accept.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class Accept < Verb
|
|
4
|
-
option :as_flag, "--as=ROLE"
|
|
5
|
-
|
|
6
|
-
def call(store)
|
|
7
|
-
key = positional.shift or raise UsageError.new("accept requires a key")
|
|
8
|
-
role = Role.resolve(flag: as_flag, env: ENV, root: store.root)
|
|
9
|
-
emit(store.accept(key, as: role))
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
data/lib/textus/cli/action.rb
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class Action < Verb
|
|
4
|
-
prepend DeprecatedAliasMixin
|
|
5
|
-
|
|
6
|
-
def self.deprecated_name = "action"
|
|
7
|
-
def self.replacement_path = "extension run"
|
|
8
|
-
|
|
9
|
-
def parse(argv)
|
|
10
|
-
@raw_argv = argv
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def call(store)
|
|
14
|
-
name = @raw_argv.shift
|
|
15
|
-
raise UsageError.new("action requires a name") if name.nil?
|
|
16
|
-
|
|
17
|
-
as_flag = nil
|
|
18
|
-
args = {}
|
|
19
|
-
@raw_argv.each do |tok|
|
|
20
|
-
case tok
|
|
21
|
-
when /\A--as=(.+)\z/ then as_flag = ::Regexp.last_match(1)
|
|
22
|
-
when /\A--format=/ then next
|
|
23
|
-
when /\A--([\w-]+)=(.*)\z/ then args[::Regexp.last_match(1)] = ::Regexp.last_match(2)
|
|
24
|
-
else
|
|
25
|
-
raise UsageError.new("unknown arg to 'action #{name}': #{tok}")
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
role = Role.resolve(flag: as_flag, env: ENV, root: store.root)
|
|
30
|
-
callable = store.registry.action(name)
|
|
31
|
-
view = StoreView.new(store, writable: true, as: role)
|
|
32
|
-
|
|
33
|
-
begin
|
|
34
|
-
Timeout.timeout(Textus::Refresh::ACTION_TIMEOUT_SECONDS) do
|
|
35
|
-
callable.call(config: {}, store: view, args: args)
|
|
36
|
-
end
|
|
37
|
-
rescue Timeout::Error
|
|
38
|
-
raise UsageError.new(
|
|
39
|
-
"action '#{name}' exceeded #{Textus::Refresh::ACTION_TIMEOUT_SECONDS}s timeout",
|
|
40
|
-
)
|
|
41
|
-
rescue Textus::Error
|
|
42
|
-
raise
|
|
43
|
-
rescue StandardError => e
|
|
44
|
-
raise UsageError.new("action '#{name}' raised: #{e.class}: #{e.message}")
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
emit({ "action" => name, "ok" => true })
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
data/lib/textus/cli/build.rb
DELETED
data/lib/textus/cli/delete.rb
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class Delete < Verb
|
|
4
|
-
option :as_flag, "--as=ROLE"
|
|
5
|
-
option :if_etag, "--if-etag=E"
|
|
6
|
-
|
|
7
|
-
def call(store)
|
|
8
|
-
key = positional.shift or raise UsageError.new("delete requires a key")
|
|
9
|
-
role = Role.resolve(flag: as_flag, env: ENV, root: store.root)
|
|
10
|
-
emit(store.delete(key, if_etag: if_etag, as: role))
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
module DeprecatedAliasMixin
|
|
4
|
-
def self.prepended(base)
|
|
5
|
-
base.extend(ClassMethods)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
module ClassMethods
|
|
9
|
-
def deprecated_name
|
|
10
|
-
raise NotImplementedError.new("#{self}.deprecated_name must be defined")
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def replacement_path
|
|
14
|
-
raise NotImplementedError.new("#{self}.replacement_path must be defined")
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
attr_writer :deprecated_alias
|
|
19
|
-
|
|
20
|
-
def call(store)
|
|
21
|
-
if @deprecated_alias
|
|
22
|
-
@stderr.puts(
|
|
23
|
-
"textus: '#{self.class.deprecated_name}' is deprecated; " \
|
|
24
|
-
"use 'textus #{self.class.replacement_path}' instead. Removed in 0.6.",
|
|
25
|
-
)
|
|
26
|
-
end
|
|
27
|
-
super
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
data/lib/textus/cli/deps.rb
DELETED
data/lib/textus/cli/doctor.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class DoctorVerb < Verb
|
|
4
|
-
option :checks, "--check=NAME"
|
|
5
|
-
|
|
6
|
-
def call(store)
|
|
7
|
-
check_list = checks&.split(",")&.map(&:strip)
|
|
8
|
-
res = Textus::Doctor.run(store, checks: check_list)
|
|
9
|
-
emit(res, exit_code: res["ok"] ? 0 : 1)
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class Extensions < Verb
|
|
4
|
-
prepend DeprecatedAliasMixin
|
|
5
|
-
|
|
6
|
-
def self.deprecated_name = "extensions"
|
|
7
|
-
def self.replacement_path = "extension list"
|
|
8
|
-
|
|
9
|
-
option :kind, "--kind=K"
|
|
10
|
-
|
|
11
|
-
def call(store) # rubocop:disable Metrics/AbcSize
|
|
12
|
-
# When invoked as the flat alias `textus extensions list`, the positional "list"
|
|
13
|
-
# is still present. When invoked via `textus extension list` (group), it has been
|
|
14
|
-
# consumed by the group dispatcher — both are valid.
|
|
15
|
-
subcommand = positional.first
|
|
16
|
-
if subcommand
|
|
17
|
-
raise UsageError.new("extensions requires 'list'") unless subcommand == "list"
|
|
18
|
-
|
|
19
|
-
positional.shift
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
rows = []
|
|
23
|
-
rows += store.registry.action_names.map { |n| { "kind" => "action", "name" => n.to_s } }
|
|
24
|
-
rows += store.registry.doctor_check_names.map { |n| { "kind" => "doctor_check", "name" => n.to_s } }
|
|
25
|
-
rows += store.registry.reducer_names.map { |n| { "kind" => "reducer", "name" => n.to_s } }
|
|
26
|
-
store.registry.hook_events.each do |evt|
|
|
27
|
-
store.registry.hooks(evt).each do |h|
|
|
28
|
-
rows << { "kind" => "hook", "event" => evt.to_s, "name" => h[:name].to_s }
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
store.manifest.entries.each do |e|
|
|
32
|
-
e.events.each do |evt, defs|
|
|
33
|
-
Array(defs).each do |defn|
|
|
34
|
-
next unless defn["exec"]
|
|
35
|
-
|
|
36
|
-
rows << {
|
|
37
|
-
"kind" => "hook", "event" => evt.to_s, "exec" => defn["exec"],
|
|
38
|
-
"key" => e.key, "as" => defn["as"] || "script"
|
|
39
|
-
}
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
rows.select! { |r| r["kind"] == kind } if kind
|
|
44
|
-
|
|
45
|
-
emit({ "extensions" => rows })
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
data/lib/textus/cli/get.rb
DELETED
data/lib/textus/cli/init.rb
DELETED
data/lib/textus/cli/intro.rb
DELETED
data/lib/textus/cli/key_group.rb
DELETED
data/lib/textus/cli/list.rb
DELETED
data/lib/textus/cli/migrate.rb
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class Migrate < Verb
|
|
4
|
-
# Does not need a store — the target manifest may still be textus/1.
|
|
5
|
-
def self.needs_store? = false
|
|
6
|
-
|
|
7
|
-
def call(_store)
|
|
8
|
-
target = positional.shift or raise UsageError.new("migrate requires a target (e.g. 'v2')")
|
|
9
|
-
raise UsageError.new("unknown migration target: #{target.inspect}; supported: v2") unless target == "v2"
|
|
10
|
-
|
|
11
|
-
# Locate the .textus directory the same way Store.discover does.
|
|
12
|
-
root = find_textus_root
|
|
13
|
-
emit(Textus::MigrateV2.run(root))
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
def find_textus_root
|
|
19
|
-
explicit = ENV.fetch("TEXTUS_ROOT", nil)
|
|
20
|
-
if explicit
|
|
21
|
-
abs = File.expand_path(explicit)
|
|
22
|
-
return abs if File.directory?(abs)
|
|
23
|
-
|
|
24
|
-
raise IoError.new("no textus store at #{abs}")
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
dir = File.expand_path(@cwd)
|
|
28
|
-
loop do
|
|
29
|
-
candidate = File.join(dir, ".textus")
|
|
30
|
-
return candidate if File.directory?(candidate) && File.exist?(File.join(candidate, "manifest.yaml"))
|
|
31
|
-
|
|
32
|
-
parent = File.dirname(dir)
|
|
33
|
-
break if parent == dir
|
|
34
|
-
|
|
35
|
-
dir = parent
|
|
36
|
-
end
|
|
37
|
-
raise IoError.new("no .textus directory found from #{@cwd}")
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class MigrateKeysVerb < Verb
|
|
4
|
-
prepend DeprecatedAliasMixin
|
|
5
|
-
|
|
6
|
-
def self.deprecated_name = "migrate-keys"
|
|
7
|
-
def self.replacement_path = "key migrate"
|
|
8
|
-
|
|
9
|
-
option :write, "--write"
|
|
10
|
-
option :dry_run, "--dry-run"
|
|
11
|
-
|
|
12
|
-
def call(store)
|
|
13
|
-
effective_write = write && !dry_run
|
|
14
|
-
res = Textus::MigrateKeys.run(store, write: effective_write || false)
|
|
15
|
-
emit(res, exit_code: res["ok"] ? 0 : 1)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
data/lib/textus/cli/mv.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class Mv < Verb
|
|
4
|
-
prepend DeprecatedAliasMixin
|
|
5
|
-
|
|
6
|
-
def self.deprecated_name = "mv"
|
|
7
|
-
def self.replacement_path = "key mv"
|
|
8
|
-
|
|
9
|
-
option :as_flag, "--as=ROLE"
|
|
10
|
-
option :dry_run, "--dry-run"
|
|
11
|
-
|
|
12
|
-
def call(store)
|
|
13
|
-
old_key = positional.shift or raise UsageError.new("mv requires <old-key> <new-key>")
|
|
14
|
-
new_key = positional.shift or raise UsageError.new("mv requires <old-key> <new-key>")
|
|
15
|
-
role = Role.resolve(flag: as_flag, env: ENV, root: store.root)
|
|
16
|
-
emit(store.mv(old_key, new_key, as: role, dry_run: dry_run || false))
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
data/lib/textus/cli/published.rb
DELETED
data/lib/textus/cli/put.rb
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class Put < Verb
|
|
4
|
-
option :as_flag, "--as=ROLE"
|
|
5
|
-
option :use_stdin, "--stdin"
|
|
6
|
-
option :action_name, "--action=NAME"
|
|
7
|
-
|
|
8
|
-
def call(store) # rubocop:disable Metrics/AbcSize
|
|
9
|
-
key = positional.shift or raise UsageError.new("put requires a key")
|
|
10
|
-
raise UsageError.new("put requires --stdin in v1") unless use_stdin
|
|
11
|
-
|
|
12
|
-
role = Role.resolve(flag: as_flag, env: ENV, root: store.root)
|
|
13
|
-
|
|
14
|
-
raw = @stdin.read
|
|
15
|
-
payload =
|
|
16
|
-
if action_name
|
|
17
|
-
callable = store.registry.action(action_name)
|
|
18
|
-
result =
|
|
19
|
-
begin
|
|
20
|
-
Timeout.timeout(Textus::Refresh::ACTION_TIMEOUT_SECONDS) do
|
|
21
|
-
callable.call(config: { "bytes" => raw }, store: Textus::StoreView.new(store), args: {})
|
|
22
|
-
end
|
|
23
|
-
rescue Timeout::Error
|
|
24
|
-
raise UsageError.new(
|
|
25
|
-
"action '#{action_name}' exceeded #{Textus::Refresh::ACTION_TIMEOUT_SECONDS}s timeout",
|
|
26
|
-
)
|
|
27
|
-
end
|
|
28
|
-
basename = key.split(".").last
|
|
29
|
-
{
|
|
30
|
-
"_meta" => {
|
|
31
|
-
"name" => basename,
|
|
32
|
-
"last_refreshed_at" => Time.now.utc.iso8601,
|
|
33
|
-
"actioned_with" => action_name,
|
|
34
|
-
}.merge(result[:_meta] || result["_meta"] || result[:frontmatter] || result["frontmatter"] || {}),
|
|
35
|
-
"body" => result[:body] || result["body"] || "",
|
|
36
|
-
}
|
|
37
|
-
else
|
|
38
|
-
JSON.parse(raw)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
meta = payload["_meta"] || payload["frontmatter"] || {}
|
|
42
|
-
body = payload["body"] || ""
|
|
43
|
-
if_etag = payload["if_etag"]
|
|
44
|
-
emit(store.put(key, meta: meta, body: body, if_etag: if_etag, as: role))
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
data/lib/textus/cli/rdeps.rb
DELETED
data/lib/textus/cli/refresh.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class RefreshVerb < Verb
|
|
4
|
-
option :as_flag, "--as=ROLE"
|
|
5
|
-
|
|
6
|
-
def call(store)
|
|
7
|
-
key = positional.shift or raise UsageError.new("refresh requires a key")
|
|
8
|
-
role = Role.resolve(flag: as_flag, env: ENV, root: store.root)
|
|
9
|
-
emit(Textus::Refresh.call(store, key, as: role))
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
data/lib/textus/cli/schema.rb
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class SchemaDiff < Verb
|
|
4
|
-
prepend DeprecatedAliasMixin
|
|
5
|
-
|
|
6
|
-
def self.deprecated_name = "schema-diff"
|
|
7
|
-
def self.replacement_path = "schema diff"
|
|
8
|
-
|
|
9
|
-
def call(store)
|
|
10
|
-
name = positional.shift or raise UsageError.new("schema-diff NAME")
|
|
11
|
-
emit(Textus::SchemaTools.diff(store, name: name))
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class SchemaGroup < Group
|
|
4
|
-
self.cli_name = "schema"
|
|
5
|
-
subcommands["show"] = SchemaVerb
|
|
6
|
-
subcommands["init"] = SchemaInit
|
|
7
|
-
subcommands["diff"] = SchemaDiff
|
|
8
|
-
subcommands["migrate"] = SchemaMigrate
|
|
9
|
-
|
|
10
|
-
# Back-compat: `textus schema KEY` (dotted key, no subcommand word).
|
|
11
|
-
# If the first positional looks like a dotted key, treat it as `schema show KEY`.
|
|
12
|
-
def parse(argv)
|
|
13
|
-
first = argv.first
|
|
14
|
-
if first && dotted_key?(first)
|
|
15
|
-
@stderr.puts(
|
|
16
|
-
"textus: 'schema KEY' is deprecated; use 'textus schema show KEY' instead. Removed in 0.6.",
|
|
17
|
-
)
|
|
18
|
-
argv.unshift("show")
|
|
19
|
-
end
|
|
20
|
-
super
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
private
|
|
24
|
-
|
|
25
|
-
def dotted_key?(token)
|
|
26
|
-
return false if token.start_with?("-")
|
|
27
|
-
return false unless token.include?(".")
|
|
28
|
-
|
|
29
|
-
token.split(".").all? { |seg| seg.match?(Manifest::KEY_SEGMENT) }
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class SchemaInit < Verb
|
|
4
|
-
prepend DeprecatedAliasMixin
|
|
5
|
-
|
|
6
|
-
def self.deprecated_name = "schema-init"
|
|
7
|
-
def self.replacement_path = "schema init"
|
|
8
|
-
|
|
9
|
-
option :from_key, "--from=KEY"
|
|
10
|
-
|
|
11
|
-
def call(store)
|
|
12
|
-
name = positional.shift or raise UsageError.new("schema-init NAME")
|
|
13
|
-
raise UsageError.new("schema-init requires --from=KEY") unless from_key
|
|
14
|
-
|
|
15
|
-
emit(Textus::SchemaTools.init(store, name: name, from: from_key))
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class SchemaMigrate < Verb
|
|
4
|
-
prepend DeprecatedAliasMixin
|
|
5
|
-
|
|
6
|
-
def self.deprecated_name = "schema-migrate"
|
|
7
|
-
def self.replacement_path = "schema migrate"
|
|
8
|
-
|
|
9
|
-
option :rename, "--rename=O:N"
|
|
10
|
-
|
|
11
|
-
def call(store)
|
|
12
|
-
name = positional.shift or raise UsageError.new("schema-migrate NAME")
|
|
13
|
-
raise UsageError.new("schema-migrate requires --rename=OLD:NEW") unless rename
|
|
14
|
-
|
|
15
|
-
emit(Textus::SchemaTools.migrate(store, name: name, rename: rename))
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
data/lib/textus/cli/stale.rb
DELETED
data/lib/textus/cli/uid.rb
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class CLI
|
|
3
|
-
class Uid < Verb
|
|
4
|
-
prepend DeprecatedAliasMixin
|
|
5
|
-
|
|
6
|
-
def self.deprecated_name = "uid"
|
|
7
|
-
def self.replacement_path = "key uid"
|
|
8
|
-
|
|
9
|
-
def call(store)
|
|
10
|
-
key = positional.shift or raise UsageError.new("uid requires a key")
|
|
11
|
-
emit({ "key" => key, "uid" => store.uid(key) })
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
data/lib/textus/cli/where.rb
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class ExtensionRegistry
|
|
3
|
-
EVENTS = %i[put delete refresh build accept].freeze
|
|
4
|
-
|
|
5
|
-
def initialize
|
|
6
|
-
@actions = {}
|
|
7
|
-
@reducers = {}
|
|
8
|
-
@hooks = {}
|
|
9
|
-
@doctor_checks = {}
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def register_action(name, &blk)
|
|
13
|
-
name = name.to_sym
|
|
14
|
-
raise UsageError.new("action '#{name}' already registered") if @actions.key?(name)
|
|
15
|
-
|
|
16
|
-
@actions[name] = blk
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def register_reducer(name, &blk)
|
|
20
|
-
name = name.to_sym
|
|
21
|
-
raise UsageError.new("reducer '#{name}' already registered") if @reducers.key?(name)
|
|
22
|
-
|
|
23
|
-
@reducers[name] = blk
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def register_hook(event, name, &blk)
|
|
27
|
-
event = event.to_sym
|
|
28
|
-
raise UsageError.new("unknown event: #{event}") unless EVENTS.include?(event)
|
|
29
|
-
|
|
30
|
-
(@hooks[event] ||= []) << { name: name.to_sym, callable: blk }
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def register_doctor_check(name, &blk)
|
|
34
|
-
name = name.to_sym
|
|
35
|
-
raise UsageError.new("doctor_check '#{name}' already registered") if @doctor_checks.key?(name)
|
|
36
|
-
|
|
37
|
-
@doctor_checks[name] = blk
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def action(name)
|
|
41
|
-
@actions[name.to_sym] or raise UsageError.new("unknown action: #{name}")
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def reducer(name)
|
|
45
|
-
@reducers[name.to_sym] or raise UsageError.new("unknown reducer: #{name}")
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def hooks(event)
|
|
49
|
-
@hooks[event.to_sym] || []
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def doctor_check(name)
|
|
53
|
-
@doctor_checks[name.to_sym] or raise UsageError.new("unknown doctor_check: #{name}")
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def action_names = @actions.keys
|
|
57
|
-
def reducer_names = @reducers.keys
|
|
58
|
-
def hook_events = @hooks.keys
|
|
59
|
-
def doctor_check_names = @doctor_checks.keys
|
|
60
|
-
end
|
|
61
|
-
end
|