textus 0.55.1 → 0.56.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 +175 -2768
- data/README.md +17 -18
- data/lib/textus/artifact.rb +8 -0
- data/lib/textus/errors.rb +2 -39
- data/lib/textus/human.rb +7 -0
- data/lib/textus/infra/adapters/concurrency_adapter.rb +15 -0
- data/lib/textus/infra/clock.rb +7 -0
- data/lib/textus/infra/database.rb +127 -0
- data/lib/textus/infra/file_system.rb +54 -0
- data/lib/textus/infra/locks.rb +50 -0
- data/lib/textus/infra/port/clock.rb +18 -0
- data/lib/textus/infra/port/publisher.rb +71 -0
- data/lib/textus/infra/port/sentinel.rb +25 -0
- data/lib/textus/infra/port/sentinel_store.rb +93 -0
- data/lib/textus/infra/store/audit_log.rb +42 -0
- data/lib/textus/infra/store/base.rb +25 -0
- data/lib/textus/infra/store/cursor_store.rb +27 -0
- data/lib/textus/infra/store/entry_index.rb +31 -0
- data/lib/textus/infra/store/envelope/meta.rb +63 -0
- data/lib/textus/infra/store/file_store.rb +23 -0
- data/lib/textus/infra/store/index/builder.rb +28 -0
- data/lib/textus/infra/store/index/lookup.rb +23 -0
- data/lib/textus/infra/store/link_store.rb +43 -0
- data/lib/textus/infra/store/workflow_queue.rb +54 -0
- data/lib/textus/infra/store.rb +29 -0
- data/lib/textus/ingest.rb +8 -0
- data/lib/textus/lanes/artifact/cache.rb +35 -0
- data/lib/textus/lanes/artifact/handlers.rb +29 -0
- data/lib/textus/lanes/artifact/lifecycle.rb +23 -0
- data/lib/textus/lanes/artifact/verbs.rb +18 -0
- data/lib/textus/lanes/ingest/dedup.rb +17 -0
- data/lib/textus/lanes/ingest/entry_types/asset.rb +45 -0
- data/lib/textus/lanes/ingest/entry_types/link.rb +16 -0
- data/lib/textus/lanes/ingest/entry_types/text.rb +17 -0
- data/lib/textus/lanes/ingest/entry_types.rb +25 -0
- data/lib/textus/lanes/ingest/handlers.rb +54 -0
- data/lib/textus/lanes/ingest/index_rebuilder.rb +13 -0
- data/lib/textus/lanes/ingest/key_builder.rb +33 -0
- data/lib/textus/lanes/ingest/resolver.rb +21 -0
- data/lib/textus/lanes/knowledge/freeform.rb +15 -0
- data/lib/textus/lanes/knowledge/handlers.rb +53 -0
- data/lib/textus/lanes/knowledge/runner.rb +45 -0
- data/lib/textus/lanes/knowledge/verbs.rb +16 -0
- data/lib/textus/lanes/scratchpad/handlers.rb +164 -0
- data/lib/textus/lanes/scratchpad/verbs.rb +73 -0
- data/lib/textus/{gate → protocol}/binder.rb +2 -10
- data/lib/textus/protocol/boot/catalog.rb +34 -0
- data/lib/textus/protocol/boot/context.rb +124 -0
- data/lib/textus/protocol/boot/protocol.rb +33 -0
- data/lib/textus/protocol/boot.rb +42 -0
- data/lib/textus/protocol/builder/domain.rb +17 -0
- data/lib/textus/protocol/builder/infrastructure.rb +17 -0
- data/lib/textus/protocol/builder/runtime.rb +46 -0
- data/lib/textus/protocol/builder.rb +11 -0
- data/lib/textus/protocol/container.rb +22 -0
- data/lib/textus/protocol/diff.rb +170 -0
- data/lib/textus/protocol/entry_constraint.rb +54 -0
- data/lib/textus/protocol/envelope.rb +70 -0
- data/lib/textus/protocol/format/base.rb +80 -0
- data/lib/textus/protocol/format/bash.rb +10 -0
- data/lib/textus/protocol/format/javascript.rb +10 -0
- data/lib/textus/protocol/format/json.rb +82 -0
- data/lib/textus/protocol/format/markdown.rb +53 -0
- data/lib/textus/protocol/format/python.rb +10 -0
- data/lib/textus/protocol/format/ruby.rb +10 -0
- data/lib/textus/protocol/format/script.rb +55 -0
- data/lib/textus/protocol/format/text.rb +48 -0
- data/lib/textus/protocol/format/yaml.rb +105 -0
- data/lib/textus/protocol/format.rb +73 -0
- data/lib/textus/protocol/freshness/ttl_evaluator.rb +61 -0
- data/lib/textus/protocol/gate.rb +61 -0
- data/lib/textus/protocol/handlers/command_context.rb +19 -0
- data/lib/textus/protocol/handlers/concern.rb +15 -0
- data/lib/textus/protocol/handlers/ops/audit_filter.rb +37 -0
- data/lib/textus/protocol/handlers/ops/bulk_planner.rb +38 -0
- data/lib/textus/protocol/handlers/ops/data_mv.rb +49 -0
- data/lib/textus/protocol/handlers/ops/git_blame.rb +65 -0
- data/lib/textus/protocol/handlers/ops/pulse_coordinator.rb +37 -0
- data/lib/textus/protocol/handlers/ops/source_expander.rb +41 -0
- data/lib/textus/protocol/handlers/query_context.rb +41 -0
- data/lib/textus/protocol/handlers/read.rb +67 -0
- data/lib/textus/protocol/handlers/system.rb +93 -0
- data/lib/textus/protocol/handlers/write.rb +57 -0
- data/lib/textus/protocol/init.rb +143 -0
- data/lib/textus/protocol/key/grammar.rb +35 -0
- data/lib/textus/protocol/key/matching.rb +23 -0
- data/lib/textus/protocol/key/path.rb +23 -0
- data/lib/textus/protocol/key.rb +25 -0
- data/lib/textus/protocol/lane.rb +12 -0
- data/lib/textus/{store/geometry.rb → protocol/layout.rb} +32 -22
- data/lib/textus/protocol/links/resolver.rb +33 -0
- data/lib/textus/protocol/links/uri_rewriter.rb +30 -0
- data/lib/textus/protocol/links.rb +10 -0
- data/lib/textus/protocol/manifest/data.rb +90 -0
- data/lib/textus/protocol/manifest/entry/base.rb +95 -0
- data/lib/textus/protocol/manifest/entry/leaf.rb +19 -0
- data/lib/textus/protocol/manifest/entry/nested.rb +19 -0
- data/lib/textus/protocol/manifest/entry/parser.rb +71 -0
- data/lib/textus/protocol/manifest/entry/publish.rb +209 -0
- data/lib/textus/protocol/manifest/entry.rb +10 -0
- data/lib/textus/protocol/manifest/policy/publish_target.rb +36 -0
- data/lib/textus/protocol/manifest/policy.rb +69 -0
- data/lib/textus/protocol/manifest/resolver.rb +156 -0
- data/lib/textus/protocol/manifest/schema/contract.rb +53 -0
- data/lib/textus/protocol/manifest/schema/validator.rb +52 -0
- data/lib/textus/protocol/manifest/schema.rb +40 -0
- data/lib/textus/protocol/manifest.rb +62 -0
- data/lib/textus/protocol/produce/render/context.rb +43 -0
- data/lib/textus/protocol/produce/render.rb +44 -0
- data/lib/textus/protocol/schema/registry.rb +44 -0
- data/lib/textus/protocol/schema/tools.rb +104 -0
- data/lib/textus/protocol/schema.rb +117 -0
- data/lib/textus/protocol/session/bridge.rb +11 -0
- data/lib/textus/protocol/session/context.rb +5 -0
- data/lib/textus/protocol/session.rb +87 -0
- data/lib/textus/protocol/store_engine/delete.rb +37 -0
- data/lib/textus/protocol/store_engine/move.rb +109 -0
- data/lib/textus/protocol/store_engine/pipeline.rb +61 -0
- data/lib/textus/protocol/store_engine/put.rb +104 -0
- data/lib/textus/protocol/store_engine.rb +86 -0
- data/lib/textus/protocol/v4.rb +25 -0
- data/lib/textus/protocol/verb_registry/arg_spec.rb +19 -0
- data/lib/textus/protocol/verb_registry/core_verbs.rb +164 -0
- data/lib/textus/protocol/verb_registry/verb_spec.rb +42 -0
- data/lib/textus/protocol/verb_registry.rb +42 -0
- data/lib/textus/surface/cli/group/{rule.rb → web.rb} +2 -2
- data/lib/textus/surface/cli/runner.rb +25 -25
- data/lib/textus/surface/cli/sources.rb +1 -3
- data/lib/textus/surface/cli/verb/get.rb +3 -6
- data/lib/textus/surface/cli/verb/init.rb +1 -1
- data/lib/textus/surface/cli/verb/put.rb +8 -6
- data/lib/textus/surface/cli/verb/web_serve.rb +22 -0
- data/lib/textus/surface/cli.rb +25 -6
- data/lib/textus/surface/dispatch.rb +17 -0
- data/lib/textus/surface/mcp/adapters/mcp_adapter.rb +28 -0
- data/lib/textus/surface/mcp/catalog.rb +26 -62
- data/lib/textus/surface/mcp/cursor_manager.rb +22 -0
- data/lib/textus/surface/mcp/drift_annotation.rb +19 -0
- data/lib/textus/surface/mcp/errors.rb +0 -10
- data/lib/textus/surface/mcp/server.rb +46 -46
- data/lib/textus/surface/watcher.rb +18 -12
- data/lib/textus/surface/web.rb +50 -0
- data/lib/textus/value/call.rb +1 -1
- data/lib/textus/{core → value}/duration.rb +1 -4
- data/lib/textus/value/etag.rb +7 -7
- data/lib/textus/value/payload.rb +7 -0
- data/lib/textus/version.rb +1 -1
- data/lib/textus/workflow/consumer.rb +39 -0
- data/lib/textus/workflow/dsl/lifecycle.rb +32 -0
- data/lib/textus/workflow/dsl/pattern_matcher.rb +20 -0
- data/lib/textus/workflow/dsl/step_builder.rb +56 -0
- data/lib/textus/workflow/dsl.rb +111 -21
- data/lib/textus/workflow/event_emitter.rb +21 -0
- data/lib/textus/workflow/publisher.rb +59 -0
- data/lib/textus/workflow/registry.rb +31 -8
- data/lib/textus/workflow/runner.rb +25 -61
- data/lib/textus/workflow/scheduler.rb +45 -0
- data/lib/textus/workflow/step_executor.rb +78 -0
- data/lib/textus/workflow/step_helpers.rb +102 -0
- data/lib/textus/workflow.rb +2 -5
- data/lib/textus.rb +16 -80
- metadata +167 -183
- data/SPEC.md +0 -908
- data/docs/architecture/README.md +0 -273
- data/docs/reference/conventions.md +0 -138
- data/lib/textus/action/accept.rb +0 -46
- data/lib/textus/action/audit.rb +0 -94
- data/lib/textus/action/base.rb +0 -42
- data/lib/textus/action/blame.rb +0 -79
- data/lib/textus/action/boot.rb +0 -15
- data/lib/textus/action/data_mv.rb +0 -58
- data/lib/textus/action/deps.rb +0 -19
- data/lib/textus/action/doctor.rb +0 -17
- data/lib/textus/action/drain.rb +0 -31
- data/lib/textus/action/enqueue.rb +0 -37
- data/lib/textus/action/get.rb +0 -34
- data/lib/textus/action/ingest.rb +0 -199
- data/lib/textus/action/jobs.rb +0 -27
- data/lib/textus/action/key_delete.rb +0 -26
- data/lib/textus/action/key_delete_prefix.rb +0 -35
- data/lib/textus/action/key_mv.rb +0 -122
- data/lib/textus/action/key_mv_prefix.rb +0 -48
- data/lib/textus/action/list.rb +0 -28
- data/lib/textus/action/propose.rb +0 -42
- data/lib/textus/action/published.rb +0 -22
- data/lib/textus/action/pulse.rb +0 -49
- data/lib/textus/action/put.rb +0 -38
- data/lib/textus/action/rdeps.rb +0 -24
- data/lib/textus/action/reject.rb +0 -28
- data/lib/textus/action/rule_explain.rb +0 -81
- data/lib/textus/action/rule_lint.rb +0 -62
- data/lib/textus/action/rule_list.rb +0 -38
- data/lib/textus/action/schema_envelope.rb +0 -22
- data/lib/textus/action/uid.rb +0 -19
- data/lib/textus/action/where.rb +0 -21
- data/lib/textus/boot.rb +0 -202
- data/lib/textus/contract/arg.rb +0 -10
- data/lib/textus/contract/dsl.rb +0 -88
- data/lib/textus/contract/spec.rb +0 -25
- data/lib/textus/contract.rb +0 -12
- data/lib/textus/core/freshness/evaluator.rb +0 -150
- data/lib/textus/core/freshness/verdict.rb +0 -34
- data/lib/textus/core/freshness.rb +0 -11
- data/lib/textus/core/retention/sweep.rb +0 -57
- data/lib/textus/core/retention.rb +0 -11
- data/lib/textus/core/sentinel.rb +0 -30
- data/lib/textus/doctor/check/audit_log.rb +0 -34
- data/lib/textus/doctor/check/generator_drift.rb +0 -29
- data/lib/textus/doctor/check/illegal_keys.rb +0 -60
- data/lib/textus/doctor/check/manifest_files.rb +0 -25
- data/lib/textus/doctor/check/notebook_sources.rb +0 -50
- data/lib/textus/doctor/check/orphaned_publish_targets.rb +0 -35
- data/lib/textus/doctor/check/proposal_targets.rb +0 -45
- data/lib/textus/doctor/check/protocol_version.rb +0 -47
- data/lib/textus/doctor/check/publish_tree_index_overlap.rb +0 -48
- data/lib/textus/doctor/check/raw_asset_paths.rb +0 -50
- data/lib/textus/doctor/check/rule_ambiguity.rb +0 -49
- data/lib/textus/doctor/check/schema_parse_error.rb +0 -28
- data/lib/textus/doctor/check/schema_violations.rb +0 -28
- data/lib/textus/doctor/check/schemas.rb +0 -26
- data/lib/textus/doctor/check/sentinels.rb +0 -60
- data/lib/textus/doctor/check/stale_reviewed_stamp.rb +0 -54
- data/lib/textus/doctor/check/templates.rb +0 -29
- data/lib/textus/doctor/check/unowned_schema_fields.rb +0 -40
- data/lib/textus/doctor/check.rb +0 -41
- data/lib/textus/doctor/validator.rb +0 -93
- data/lib/textus/doctor.rb +0 -54
- data/lib/textus/format/base.rb +0 -49
- data/lib/textus/format/json.rb +0 -102
- data/lib/textus/format/markdown.rb +0 -80
- data/lib/textus/format/shared.rb +0 -17
- data/lib/textus/format/text.rb +0 -55
- data/lib/textus/format/yaml.rb +0 -125
- data/lib/textus/format.rb +0 -46
- data/lib/textus/gate/auth.rb +0 -212
- data/lib/textus/gate.rb +0 -92
- data/lib/textus/init.rb +0 -157
- data/lib/textus/jobs.rb +0 -9
- data/lib/textus/key/distance.rb +0 -55
- data/lib/textus/key/grammar.rb +0 -33
- data/lib/textus/key/matching.rb +0 -24
- data/lib/textus/key/path.rb +0 -28
- data/lib/textus/manifest/capabilities.rb +0 -29
- data/lib/textus/manifest/data.rb +0 -102
- data/lib/textus/manifest/entry/base.rb +0 -105
- data/lib/textus/manifest/entry/ignore_matcher.rb +0 -46
- data/lib/textus/manifest/entry/leaf.rb +0 -17
- data/lib/textus/manifest/entry/nested.rb +0 -37
- data/lib/textus/manifest/entry/parser.rb +0 -99
- data/lib/textus/manifest/entry/produced.rb +0 -36
- data/lib/textus/manifest/entry/publish/mode.rb +0 -45
- data/lib/textus/manifest/entry/publish/none.rb +0 -14
- data/lib/textus/manifest/entry/publish/subtree_mirror.rb +0 -73
- data/lib/textus/manifest/entry/publish/template.rb +0 -16
- data/lib/textus/manifest/entry/publish/to_paths.rb +0 -76
- data/lib/textus/manifest/entry/publish/tree.rb +0 -50
- data/lib/textus/manifest/entry/publish.rb +0 -45
- data/lib/textus/manifest/entry/validators/format_matrix.rb +0 -21
- data/lib/textus/manifest/entry/validators/ignore.rb +0 -28
- data/lib/textus/manifest/entry/validators/publish.rb +0 -30
- data/lib/textus/manifest/entry/validators.rb +0 -18
- data/lib/textus/manifest/entry.rb +0 -8
- data/lib/textus/manifest/policy/matcher.rb +0 -51
- data/lib/textus/manifest/policy/publish_target.rb +0 -34
- data/lib/textus/manifest/policy/react.rb +0 -30
- data/lib/textus/manifest/policy/retention.rb +0 -29
- data/lib/textus/manifest/policy/source.rb +0 -30
- data/lib/textus/manifest/policy.rb +0 -95
- data/lib/textus/manifest/resolver.rb +0 -118
- data/lib/textus/manifest/rules.rb +0 -86
- data/lib/textus/manifest/schema/contract.rb +0 -61
- data/lib/textus/manifest/schema/keys.rb +0 -90
- data/lib/textus/manifest/schema/semantics/cross_field.rb +0 -53
- data/lib/textus/manifest/schema/semantics/invariants.rb +0 -125
- data/lib/textus/manifest/schema/semantics/migration.rb +0 -83
- data/lib/textus/manifest/schema/semantics.rb +0 -27
- data/lib/textus/manifest/schema/validator.rb +0 -48
- data/lib/textus/manifest/schema/vocabulary.rb +0 -25
- data/lib/textus/manifest/schema.rb +0 -30
- data/lib/textus/manifest.rb +0 -65
- data/lib/textus/meta.rb +0 -54
- data/lib/textus/port/audit_log.rb +0 -268
- data/lib/textus/port/build_lock.rb +0 -64
- data/lib/textus/port/clock.rb +0 -10
- data/lib/textus/port/publisher.rb +0 -60
- data/lib/textus/port/sentinel_store.rb +0 -83
- data/lib/textus/port/storage/file_stat.rb +0 -19
- data/lib/textus/port/storage/file_store.rb +0 -26
- data/lib/textus/port/store.rb +0 -93
- data/lib/textus/port/watcher_lock.rb +0 -48
- data/lib/textus/produce/engine.rb +0 -50
- data/lib/textus/produce/render.rb +0 -20
- data/lib/textus/schema/tools.rb +0 -115
- data/lib/textus/schema.rb +0 -100
- data/lib/textus/schemas.rb +0 -54
- data/lib/textus/store/compositor.rb +0 -34
- data/lib/textus/store/container.rb +0 -43
- data/lib/textus/store/cursor.rb +0 -26
- data/lib/textus/store/envelope/reader.rb +0 -43
- data/lib/textus/store/envelope/writer.rb +0 -195
- data/lib/textus/store/index/builder.rb +0 -74
- data/lib/textus/store/index/lookup.rb +0 -60
- data/lib/textus/store/jobs/base.rb +0 -13
- data/lib/textus/store/jobs/index.rb +0 -15
- data/lib/textus/store/jobs/materialize.rb +0 -15
- data/lib/textus/store/jobs/plan.rb +0 -11
- data/lib/textus/store/jobs/planner.rb +0 -104
- data/lib/textus/store/jobs/queue.rb +0 -154
- data/lib/textus/store/jobs/registry.rb +0 -19
- data/lib/textus/store/jobs/retention.rb +0 -50
- data/lib/textus/store/jobs/sweep.rb +0 -21
- data/lib/textus/store/jobs/worker.rb +0 -64
- data/lib/textus/store/session.rb +0 -37
- data/lib/textus/store.rb +0 -99
- data/lib/textus/surface/cli/verb/doctor.rb +0 -19
- data/lib/textus/surface/cli/verb/schema_diff.rb +0 -17
- data/lib/textus/surface/cli/verb/schema_init.rb +0 -21
- data/lib/textus/surface/cli/verb/schema_migrate.rb +0 -21
- data/lib/textus/surface/mcp.rb +0 -8
- data/lib/textus/surface/projector.rb +0 -27
- data/lib/textus/surface/role_scope.rb +0 -34
- data/lib/textus/value/command.rb +0 -16
- data/lib/textus/value/envelope.rb +0 -89
- data/lib/textus/value/result.rb +0 -26
- data/lib/textus/workflow/collector.rb +0 -27
- data/lib/textus/workflow/context.rb +0 -5
- data/lib/textus/workflow/loader.rb +0 -17
- data/lib/textus/workflow/pattern.rb +0 -18
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
require "fileutils"
|
|
2
|
-
|
|
3
|
-
module Textus
|
|
4
|
-
class Store
|
|
5
|
-
module Jobs
|
|
6
|
-
class Retention
|
|
7
|
-
def initialize(container:, call:)
|
|
8
|
-
@container = container
|
|
9
|
-
@call = call
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def call(rows)
|
|
13
|
-
out = { dropped: [], archived: [], failed: [] }
|
|
14
|
-
rows.each do |row|
|
|
15
|
-
key = row["key"]
|
|
16
|
-
begin
|
|
17
|
-
case row["action"]
|
|
18
|
-
when "drop"
|
|
19
|
-
delete(key)
|
|
20
|
-
out[:dropped] << key
|
|
21
|
-
when "archive"
|
|
22
|
-
archive_leaf(row)
|
|
23
|
-
delete(key)
|
|
24
|
-
out[:archived] << key
|
|
25
|
-
end
|
|
26
|
-
rescue Textus::Error => e
|
|
27
|
-
out[:failed] << { "key" => key, "error" => e.message }
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
out
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
private
|
|
34
|
-
|
|
35
|
-
def archive_leaf(row)
|
|
36
|
-
src = row["path"]
|
|
37
|
-
root = @container.root.to_s
|
|
38
|
-
rel = src.delete_prefix("#{root}/")
|
|
39
|
-
dest = File.join(root, "archive", rel)
|
|
40
|
-
FileUtils.mkdir_p(File.dirname(dest))
|
|
41
|
-
FileUtils.cp(src, dest)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def delete(key)
|
|
45
|
-
Textus::Action::KeyDelete.call(container: @container, call: @call, key: key)
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class Store
|
|
3
|
-
module Jobs
|
|
4
|
-
class Sweep < Base
|
|
5
|
-
REQUIRED_ROLE = Textus::Value::Role::AUTOMATION
|
|
6
|
-
TYPE = "sweep"
|
|
7
|
-
|
|
8
|
-
def self.call(container:, call:, scope: {}, key: nil)
|
|
9
|
-
prefix = key || (scope.is_a?(Hash) ? scope["prefix"] : nil)
|
|
10
|
-
lane = scope.is_a?(Hash) ? scope["lane"] : nil
|
|
11
|
-
rows = Textus::Core::Retention::Sweep.new(
|
|
12
|
-
manifest: container.manifest,
|
|
13
|
-
file_stat: Textus::Port::Storage::FileStat.new,
|
|
14
|
-
clock: Textus::Port::Clock.new,
|
|
15
|
-
).call(prefix: prefix, lane: lane)
|
|
16
|
-
Textus::Store::Jobs::Retention.new(container: container, call: call).call(rows)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class Store
|
|
3
|
-
module Jobs
|
|
4
|
-
class Worker
|
|
5
|
-
Summary = Struct.new(:completed, :failed, keyword_init: true)
|
|
6
|
-
|
|
7
|
-
def self.for(container:, queue:)
|
|
8
|
-
new(queue: queue, container: container,
|
|
9
|
-
lease_ttl: container.manifest.data.worker_config[:lease_ttl])
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def initialize(queue:, container:, lease_ttl: 60)
|
|
13
|
-
@queue = queue
|
|
14
|
-
@container = container
|
|
15
|
-
@lease_ttl = lease_ttl
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def drain(worker_id: "drain-#{Process.pid}")
|
|
19
|
-
completed = 0
|
|
20
|
-
failed = 0
|
|
21
|
-
loop do
|
|
22
|
-
leased = @queue.lease(worker_id: worker_id, lease_ttl: @lease_ttl)
|
|
23
|
-
break unless leased
|
|
24
|
-
|
|
25
|
-
case run_one(leased)
|
|
26
|
-
when :completed then completed += 1
|
|
27
|
-
when :dead_lettered then failed += 1
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
Summary.new(completed: completed, failed: failed)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def drain_pool(pool: 4)
|
|
34
|
-
summaries = []
|
|
35
|
-
mutex = Mutex.new
|
|
36
|
-
threads = Array.new(pool) do |i|
|
|
37
|
-
Thread.new do
|
|
38
|
-
s = drain(worker_id: "pool-#{Process.pid}-#{i}")
|
|
39
|
-
mutex.synchronize { summaries << s }
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
threads.each(&:join)
|
|
43
|
-
Summary.new(completed: summaries.sum(&:completed), failed: summaries.sum(&:failed))
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
private
|
|
47
|
-
|
|
48
|
-
def run_one(leased)
|
|
49
|
-
job = leased.job
|
|
50
|
-
klass = Textus::Jobs.fetch(job.type)
|
|
51
|
-
call = Textus::Value::Call.build(
|
|
52
|
-
role: job.role || Textus::Value::Role::AUTOMATION,
|
|
53
|
-
correlation_id: SecureRandom.uuid,
|
|
54
|
-
)
|
|
55
|
-
klass.call(container: @container, call: call, **job.args.transform_keys(&:to_sym))
|
|
56
|
-
@queue.ack(leased)
|
|
57
|
-
:completed
|
|
58
|
-
rescue StandardError => e
|
|
59
|
-
@queue.fail(leased, error: e.message)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
data/lib/textus/store/session.rb
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "dry-struct"
|
|
4
|
-
|
|
5
|
-
module Textus
|
|
6
|
-
# The agent session: per-connection (MCP), per-process (CLI), or per-loop
|
|
7
|
-
# (Ruby) orientation state — the audit cursor plus the contract etag and
|
|
8
|
-
# propose_lane captured at boot. Immutable Dry::Struct::Value; advance_cursor
|
|
9
|
-
# and with return new instances. ADR 0036; contract_etag widened in ADR 0074.
|
|
10
|
-
class Store
|
|
11
|
-
class Session < Dry::Struct
|
|
12
|
-
attribute :role, Value::Types::RoleName
|
|
13
|
-
attribute :cursor, Value::Types::Cursor
|
|
14
|
-
attribute :propose_lane, Value::Types::String.optional
|
|
15
|
-
attribute :contract_etag, Value::Types::String
|
|
16
|
-
|
|
17
|
-
def with(**attrs) = self.class.new(to_h.merge(attrs))
|
|
18
|
-
|
|
19
|
-
def advance_cursor(new_cursor) = with(cursor: new_cursor)
|
|
20
|
-
|
|
21
|
-
def check_etag!(observed_etag)
|
|
22
|
-
return if observed_etag == contract_etag
|
|
23
|
-
|
|
24
|
-
raise Textus::ContractDrift.new(
|
|
25
|
-
"contract changed (manifest/hooks/schemas were #{short_etag(contract_etag)}, " \
|
|
26
|
-
"now #{short_etag(observed_etag)}); re-run boot",
|
|
27
|
-
)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
private
|
|
31
|
-
|
|
32
|
-
# First 8 hex chars after the "sha256:" prefix — a stable short id for
|
|
33
|
-
# the drift diagnostic.
|
|
34
|
-
def short_etag(etag) = etag.to_s.delete_prefix("sha256:")[0, 8]
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
end
|
data/lib/textus/store.rb
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
require "fileutils"
|
|
2
|
-
|
|
3
|
-
module Textus
|
|
4
|
-
class Store
|
|
5
|
-
attr_reader :container
|
|
6
|
-
|
|
7
|
-
# Readers are derived from the Container's schema, so the field set lives
|
|
8
|
-
# in exactly one place (Container). A new capability added there is
|
|
9
|
-
# automatically exposed on the Store.
|
|
10
|
-
Textus::Store::Container.attribute_names.each do |field|
|
|
11
|
-
define_method(field) { @container.public_send(field) }
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.discover(start_dir = Dir.pwd, root: nil)
|
|
15
|
-
explicit = root || ENV.fetch("TEXTUS_ROOT", nil)
|
|
16
|
-
return discover_explicit(explicit) if explicit
|
|
17
|
-
|
|
18
|
-
ascend_for_store(File.expand_path(start_dir)) ||
|
|
19
|
-
raise(IoError.new("no .textus directory found from #{start_dir}"))
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
private_class_method def self.ascend_for_store(dir)
|
|
23
|
-
loop do
|
|
24
|
-
candidate = File.join(dir, ".textus")
|
|
25
|
-
return new(candidate) if store_dir?(candidate)
|
|
26
|
-
|
|
27
|
-
parent = File.dirname(dir)
|
|
28
|
-
return nil if parent == dir
|
|
29
|
-
|
|
30
|
-
dir = parent
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
private_class_method def self.discover_explicit(root_arg)
|
|
35
|
-
abs = File.expand_path(root_arg)
|
|
36
|
-
raise IoError.new("no textus store at #{abs}") unless store_dir?(abs)
|
|
37
|
-
|
|
38
|
-
new(abs)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
private_class_method def self.store_dir?(dir)
|
|
42
|
-
File.directory?(dir) && File.exist?(File.join(dir, "manifest.yaml"))
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def initialize(root)
|
|
46
|
-
@container = build_container(File.expand_path(root))
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Build an agent Session oriented at the current cursor/manifest — the
|
|
50
|
-
# Ruby equivalent of an MCP `initialize`. ADR 0036.
|
|
51
|
-
def session(role:)
|
|
52
|
-
Textus::Store::Session.new(
|
|
53
|
-
role: role.to_s,
|
|
54
|
-
cursor: audit_log.latest_seq,
|
|
55
|
-
propose_lane: manifest.policy.propose_lane_for(role),
|
|
56
|
-
contract_etag: Textus::Value::Etag.for_contract(root),
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def gate
|
|
61
|
-
@container.gate
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def as(role, dry_run: false, correlation_id: nil)
|
|
65
|
-
Textus::Surface::RoleScope.new(container: container, role: role, dry_run: dry_run, correlation_id: correlation_id)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
private
|
|
69
|
-
|
|
70
|
-
def build_container(root)
|
|
71
|
-
manifest = Manifest.load(root)
|
|
72
|
-
job_store = Port::Store.new(root: root).setup!
|
|
73
|
-
geometry = Store::Geometry.new(root)
|
|
74
|
-
infra = Container::Infrastructure.new(
|
|
75
|
-
file_store: Port::Storage::FileStore.new,
|
|
76
|
-
schemas: Schemas.new(geometry.schemas_dir),
|
|
77
|
-
audit_log: Port::AuditLog.new(
|
|
78
|
-
root,
|
|
79
|
-
max_size: manifest.data.audit_config[:max_size],
|
|
80
|
-
keep: manifest.data.audit_config[:keep],
|
|
81
|
-
),
|
|
82
|
-
job_store:,
|
|
83
|
-
geometry:,
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
coord = Container::Coordination.new(
|
|
87
|
-
manifest:,
|
|
88
|
-
workflows: Workflow::Loader.load_all(root),
|
|
89
|
-
gate: nil,
|
|
90
|
-
compositor: nil,
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
container = Container.new(infra, coord)
|
|
94
|
-
compositor = Store::Compositor.new(container)
|
|
95
|
-
gate = Textus::Gate.new(container)
|
|
96
|
-
container.wire_gate!(gate, compositor)
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Surface
|
|
3
|
-
class CLI
|
|
4
|
-
class Verb
|
|
5
|
-
class Doctor < Verb
|
|
6
|
-
command_name "doctor"
|
|
7
|
-
option :checks, "--check=NAME"
|
|
8
|
-
|
|
9
|
-
def call(store)
|
|
10
|
-
spec = Textus::Action::Doctor.contract
|
|
11
|
-
inputs = { checks: checks&.split(",")&.map(&:strip) }
|
|
12
|
-
res = store.gate.dispatch(spec: spec, inputs: inputs, role: resolved_role(store))
|
|
13
|
-
emit(res, exit_code: res["ok"] ? 0 : 1)
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Surface
|
|
3
|
-
class CLI
|
|
4
|
-
class Verb
|
|
5
|
-
class SchemaDiff < Verb
|
|
6
|
-
command_name "diff"
|
|
7
|
-
parent_group Group::Schema
|
|
8
|
-
|
|
9
|
-
def call(store)
|
|
10
|
-
name = positional.shift or raise UsageError.new("schema diff NAME")
|
|
11
|
-
emit(Textus::Schema::Tools.diff(store, name: name))
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Surface
|
|
3
|
-
class CLI
|
|
4
|
-
class Verb
|
|
5
|
-
class SchemaInit < Verb
|
|
6
|
-
command_name "init"
|
|
7
|
-
parent_group Group::Schema
|
|
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::Schema::Tools.init(store, name: name, from: from_key))
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Surface
|
|
3
|
-
class CLI
|
|
4
|
-
class Verb
|
|
5
|
-
class SchemaMigrate < Verb
|
|
6
|
-
command_name "migrate"
|
|
7
|
-
parent_group Group::Schema
|
|
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::Schema::Tools.migrate(store, name: name, rename: rename))
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
data/lib/textus/surface/mcp.rb
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Surface
|
|
3
|
-
class Projector
|
|
4
|
-
def initialize(view_key: :default, binder_method: :inputs_from_wire)
|
|
5
|
-
@view_key = view_key
|
|
6
|
-
@binder_method = binder_method
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def verbs(action_verbs = Textus::Action::VERBS)
|
|
10
|
-
action_verbs.select do |_verb, klass|
|
|
11
|
-
klass.respond_to?(:contract?) && klass.contract?
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def names(action_verbs = Textus::Action::VERBS)
|
|
16
|
-
verbs(action_verbs).keys.map(&:to_s)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def dispatch(verb_name, inputs:, store:, role:, session: nil)
|
|
20
|
-
klass = Textus::Action::VERBS.fetch(verb_name.to_sym)
|
|
21
|
-
spec = klass.contract
|
|
22
|
-
bound = Textus::Gate::Binder.public_send(@binder_method, spec, inputs)
|
|
23
|
-
store.gate.dispatch(spec:, inputs: bound, role:, session:, surface: @view_key)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Textus
|
|
4
|
-
module Surface
|
|
5
|
-
# Role-scoped identity carrier. Holds the acting identity (role,
|
|
6
|
-
# correlation_id, dry_run) bound to a container. All verb methods
|
|
7
|
-
# (put, get, accept, ...) are injected by textus.rb's define_method
|
|
8
|
-
# loop, which dispatches directly through Gate.
|
|
9
|
-
class RoleScope
|
|
10
|
-
attr_reader :container, :role, :correlation_id
|
|
11
|
-
|
|
12
|
-
def initialize(container:, role:, dry_run: false, correlation_id: nil)
|
|
13
|
-
@container = container
|
|
14
|
-
@role = role.to_s
|
|
15
|
-
@dry_run = dry_run
|
|
16
|
-
@correlation_id = correlation_id || SecureRandom.uuid
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def dry_run? = !!@dry_run
|
|
20
|
-
|
|
21
|
-
def with_role(role)
|
|
22
|
-
self.class.new(container: @container, role:, dry_run: @dry_run, correlation_id: @correlation_id)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def with_correlation_id(cid)
|
|
26
|
-
self.class.new(container: @container, role: @role, dry_run: @dry_run, correlation_id: cid)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def with_dry_run
|
|
30
|
-
self.class.new(container: @container, role: @role, dry_run: true, correlation_id: @correlation_id)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
data/lib/textus/value/command.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Value
|
|
3
|
-
Command = Data.define(:verb, :params, :role) do
|
|
4
|
-
def initialize(verb:, params:, role:)
|
|
5
|
-
super
|
|
6
|
-
params.freeze
|
|
7
|
-
freeze
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def [](key) = params[key]
|
|
11
|
-
def key = params[:key]
|
|
12
|
-
def pending_key = params[:pending_key]
|
|
13
|
-
def dry_run = params[:dry_run]
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "dry-struct"
|
|
4
|
-
|
|
5
|
-
module Textus
|
|
6
|
-
module Value
|
|
7
|
-
class Envelope < Dry::Struct
|
|
8
|
-
attribute :protocol, Types::String
|
|
9
|
-
attribute :key, Types::String
|
|
10
|
-
attribute :lane, Types::String
|
|
11
|
-
attribute :owner, Types::String.optional
|
|
12
|
-
attribute :path, Types::String
|
|
13
|
-
attribute :format, Types::FormatName
|
|
14
|
-
attribute :etag, Types::String
|
|
15
|
-
attribute :uid, Types::String.optional
|
|
16
|
-
attribute :sources, Types::Array.of(Types::String).optional
|
|
17
|
-
attribute :schema_ref, Types::String.optional
|
|
18
|
-
attribute :meta, Types::Hash.default({}.freeze)
|
|
19
|
-
attribute :body, Types::String.optional
|
|
20
|
-
attribute :content, Types::Any.optional
|
|
21
|
-
attribute :freshness, Types::Any.optional
|
|
22
|
-
|
|
23
|
-
# rubocop:disable Metrics/ParameterLists
|
|
24
|
-
def self.build(key:, mentry:, path:, meta:, body:, etag:, content: nil, freshness: nil)
|
|
25
|
-
# rubocop:enable Metrics/ParameterLists
|
|
26
|
-
new(
|
|
27
|
-
protocol: Textus::PROTOCOL,
|
|
28
|
-
key: key,
|
|
29
|
-
lane: mentry.lane,
|
|
30
|
-
owner: mentry.owner,
|
|
31
|
-
path: path,
|
|
32
|
-
format: mentry.format,
|
|
33
|
-
uid: extract_uid(meta),
|
|
34
|
-
sources: extract_sources(meta),
|
|
35
|
-
etag: etag,
|
|
36
|
-
schema_ref: mentry.schema,
|
|
37
|
-
meta: meta,
|
|
38
|
-
body: body,
|
|
39
|
-
content: content,
|
|
40
|
-
freshness: freshness,
|
|
41
|
-
)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def self.extract_uid(meta)
|
|
45
|
-
v = meta.is_a?(Hash) ? meta["uid"] : nil
|
|
46
|
-
v.is_a?(String) ? v : nil
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def self.extract_sources(meta)
|
|
50
|
-
v = meta.is_a?(Hash) ? meta["sources"] : nil
|
|
51
|
-
v.is_a?(Array) && !v.empty? ? v : nil
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def with(**attrs) = self.class.new(to_h.merge(attrs))
|
|
55
|
-
|
|
56
|
-
def to_h_for_wire
|
|
57
|
-
h = {
|
|
58
|
-
"protocol" => protocol,
|
|
59
|
-
"key" => key,
|
|
60
|
-
"lane" => lane,
|
|
61
|
-
"owner" => owner,
|
|
62
|
-
"path" => path,
|
|
63
|
-
"format" => format,
|
|
64
|
-
"_meta" => meta,
|
|
65
|
-
"body" => body,
|
|
66
|
-
"etag" => etag,
|
|
67
|
-
"schema_ref" => schema_ref,
|
|
68
|
-
"uid" => uid,
|
|
69
|
-
}
|
|
70
|
-
h["sources"] = sources if sources
|
|
71
|
-
h["content"] = content unless content.nil?
|
|
72
|
-
freshness&.to_h_for_wire&.each { |k, v| h[k] = v }
|
|
73
|
-
h
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def stale?
|
|
77
|
-
return false if freshness.nil?
|
|
78
|
-
|
|
79
|
-
freshness.stale == true
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def fetching?
|
|
83
|
-
return false if freshness.nil?
|
|
84
|
-
|
|
85
|
-
freshness.fetching == true
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
data/lib/textus/value/result.rb
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Textus
|
|
4
|
-
module Value
|
|
5
|
-
# Unwraps Dry::Monads results at the Gate seam.
|
|
6
|
-
# Every action returns Success(value) or Failure(code:, message:, details:).
|
|
7
|
-
# This module converts Failure into an ActionError for surfaces (CLI, MCP)
|
|
8
|
-
# that expect exceptions.
|
|
9
|
-
module Result
|
|
10
|
-
def self.unwrap(result)
|
|
11
|
-
case result
|
|
12
|
-
when Dry::Monads::Result::Success then result.value!
|
|
13
|
-
when Dry::Monads::Result::Failure
|
|
14
|
-
failure = result.failure
|
|
15
|
-
raise ActionError.new(
|
|
16
|
-
failure[:code] || :internal,
|
|
17
|
-
failure[:message] || "action failed",
|
|
18
|
-
details: failure[:details] || {},
|
|
19
|
-
)
|
|
20
|
-
else
|
|
21
|
-
result
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Workflow
|
|
3
|
-
class Collector
|
|
4
|
-
@current = nil
|
|
5
|
-
|
|
6
|
-
class << self
|
|
7
|
-
attr_reader :current
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.with(collector)
|
|
11
|
-
prev = @current
|
|
12
|
-
@current = collector
|
|
13
|
-
yield
|
|
14
|
-
ensure
|
|
15
|
-
@current = prev
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def initialize(registry)
|
|
19
|
-
@registry = registry
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def register(defn)
|
|
23
|
-
@registry.register(defn)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Workflow
|
|
3
|
-
class Loader
|
|
4
|
-
def self.load_all(root)
|
|
5
|
-
geometry = Textus::Store::Geometry.new(root)
|
|
6
|
-
registry = Registry.new
|
|
7
|
-
return registry unless File.directory?(geometry.workflow_dir)
|
|
8
|
-
|
|
9
|
-
collector = Collector.new(registry)
|
|
10
|
-
Collector.with(collector) do
|
|
11
|
-
Dir.glob(File.join(geometry.workflow_dir, "**", "*.rb")).each { |path| load path }
|
|
12
|
-
end
|
|
13
|
-
registry
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
module Workflow
|
|
3
|
-
module Pattern
|
|
4
|
-
def self.match?(pattern, key)
|
|
5
|
-
if pattern.end_with?(".**")
|
|
6
|
-
prefix = pattern.delete_suffix(".**")
|
|
7
|
-
key.start_with?("#{prefix}.")
|
|
8
|
-
elsif pattern.end_with?(".*")
|
|
9
|
-
prefix = pattern.delete_suffix(".*")
|
|
10
|
-
suffix = key.delete_prefix("#{prefix}.")
|
|
11
|
-
key != suffix && !suffix.include?(".")
|
|
12
|
-
else
|
|
13
|
-
key == pattern
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|