textus 0.8.1 → 0.10.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 +329 -0
- data/README.md +50 -22
- data/SPEC.md +194 -63
- data/docs/architecture.md +22 -4
- data/docs/conventions.md +24 -17
- data/lib/textus/application/context.rb +44 -0
- data/lib/textus/application/reads/audit.rb +69 -0
- data/lib/textus/application/reads/blame.rb +79 -0
- data/lib/textus/application/reads/freshness.rb +77 -0
- data/lib/textus/application/reads/get.rb +62 -0
- data/lib/textus/application/reads/policy_explain.rb +39 -0
- data/lib/textus/application/refresh/all.rb +41 -0
- data/lib/textus/application/refresh/orchestrator.rb +69 -0
- data/lib/textus/application/refresh/worker.rb +79 -0
- data/lib/textus/application/writes/accept.rb +44 -0
- data/lib/textus/application/writes/build.rb +116 -0
- data/lib/textus/application/writes/delete.rb +36 -0
- data/lib/textus/application/writes/publish.rb +25 -0
- data/lib/textus/application/writes/put.rb +43 -0
- data/lib/textus/builder/pipeline.rb +1 -1
- data/lib/textus/builder/renderer/json.rb +1 -1
- data/lib/textus/builder/renderer/markdown.rb +1 -1
- data/lib/textus/builder/renderer/text.rb +1 -1
- data/lib/textus/builder/renderer/yaml.rb +1 -1
- data/lib/textus/builder/renderer.rb +1 -1
- data/lib/textus/cli/group/policy.rb +11 -0
- data/lib/textus/cli/verb/accept.rb +2 -2
- data/lib/textus/cli/verb/audit.rb +30 -0
- data/lib/textus/cli/verb/blame.rb +16 -0
- data/lib/textus/cli/verb/build.rb +2 -1
- data/lib/textus/cli/verb/delete.rb +2 -2
- data/lib/textus/cli/verb/freshness.rb +16 -0
- data/lib/textus/cli/verb/get.rb +7 -1
- data/lib/textus/cli/verb/hook_run.rb +4 -4
- data/lib/textus/cli/verb/mv.rb +1 -2
- data/lib/textus/cli/verb/policy_explain.rb +14 -0
- data/lib/textus/cli/verb/policy_list.rb +25 -0
- data/lib/textus/cli/verb/put.rb +10 -8
- data/lib/textus/cli/verb/refresh.rb +2 -2
- data/lib/textus/cli/verb/refresh_stale.rb +18 -0
- data/lib/textus/cli/verb/reject.rb +14 -0
- data/lib/textus/cli/verb.rb +14 -0
- data/lib/textus/cli.rb +16 -2
- data/lib/textus/composition.rb +72 -0
- data/lib/textus/doctor/check/handler_allowlist.rb +33 -0
- data/lib/textus/doctor/check/intake_registration.rb +46 -0
- data/lib/textus/doctor/check/legacy_intake_fields.rb +57 -0
- data/lib/textus/doctor/check/policy_ambiguity.rb +49 -0
- data/lib/textus/doctor.rb +7 -1
- data/lib/textus/domain/action.rb +9 -0
- data/lib/textus/domain/freshness/evaluator.rb +30 -0
- data/lib/textus/domain/freshness/policy.rb +18 -0
- data/lib/textus/domain/freshness/verdict.rb +12 -0
- data/lib/textus/domain/outcome.rb +10 -0
- data/lib/textus/domain/permission.rb +15 -0
- data/lib/textus/domain/policy/handler_allowlist.rb +17 -0
- data/lib/textus/domain/policy/matcher.rb +51 -0
- data/lib/textus/domain/policy/promote.rb +24 -0
- data/lib/textus/domain/policy/refresh.rb +48 -0
- data/lib/textus/domain/policy.rb +7 -0
- data/lib/textus/hooks/builtin.rb +5 -5
- data/lib/textus/hooks/dispatcher.rb +15 -1
- data/lib/textus/hooks/dsl.rb +18 -0
- data/lib/textus/hooks/registry.rb +12 -5
- data/lib/textus/infra/clock.rb +9 -0
- data/lib/textus/infra/event_bus.rb +27 -0
- data/lib/textus/infra/publisher.rb +73 -0
- data/lib/textus/infra/refresh/detached.rb +38 -0
- data/lib/textus/infra/refresh/lock.rb +44 -0
- data/lib/textus/init.rb +71 -28
- data/lib/textus/intro.rb +17 -14
- data/lib/textus/manifest/entry.rb +39 -13
- data/lib/textus/manifest/policies.rb +83 -0
- data/lib/textus/manifest.rb +30 -11
- data/lib/textus/projection.rb +1 -1
- data/lib/textus/proposal.rb +4 -21
- data/lib/textus/refresh.rb +9 -45
- data/lib/textus/store/mover.rb +14 -9
- data/lib/textus/store/reader.rb +10 -8
- data/lib/textus/store/staleness.rb +5 -17
- data/lib/textus/store/validator.rb +46 -20
- data/lib/textus/store/writer.rb +51 -14
- data/lib/textus/store.rb +30 -10
- data/lib/textus/version.rb +1 -1
- data/lib/textus.rb +1 -0
- metadata +46 -5
- data/lib/textus/builder.rb +0 -86
- data/lib/textus/cli/verb/stale.rb +0 -14
- data/lib/textus/publisher.rb +0 -71
- data/lib/textus/store/view.rb +0 -29
data/lib/textus/publisher.rb
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
require "json"
|
|
2
|
-
require "digest"
|
|
3
|
-
require "fileutils"
|
|
4
|
-
|
|
5
|
-
module Textus
|
|
6
|
-
# Publishes built artifacts from the store to repo-relative consumer paths.
|
|
7
|
-
# Publish = copy + sentinel. The in-store file is already the consumer-shaped
|
|
8
|
-
# artifact; no parsing or stripping. Sentinels live under
|
|
9
|
-
# `<store_root>/sentinels/` and mirror the target's repo-relative layout so
|
|
10
|
-
# consumer directories aren't polluted with `.textus-managed.json` siblings.
|
|
11
|
-
module Publisher
|
|
12
|
-
SENTINEL_SUFFIX = ".textus-managed.json".freeze
|
|
13
|
-
SENTINEL_DIR = "sentinels".freeze
|
|
14
|
-
|
|
15
|
-
def self.publish(source:, target:, store_root:)
|
|
16
|
-
FileUtils.mkdir_p(File.dirname(target))
|
|
17
|
-
refuse_if_unmanaged(target, store_root)
|
|
18
|
-
File.delete(target) if File.symlink?(target)
|
|
19
|
-
FileUtils.cp(source, target)
|
|
20
|
-
write_sentinel(target, store_root: store_root, source: source)
|
|
21
|
-
cleanup_legacy_sentinel(target)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def self.refuse_if_unmanaged(target, store_root)
|
|
25
|
-
return unless File.exist?(target) || File.symlink?(target)
|
|
26
|
-
return if managed?(target, store_root)
|
|
27
|
-
|
|
28
|
-
raise PublishError.new("refusing to clobber unmanaged file at #{target}", target: target)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def self.managed?(target, store_root)
|
|
32
|
-
File.exist?(sentinel_path(target, store_root)) || File.exist?(legacy_sentinel_path(target))
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def self.write_sentinel(target, store_root:, source:)
|
|
36
|
-
path = sentinel_path(target, store_root)
|
|
37
|
-
FileUtils.mkdir_p(File.dirname(path))
|
|
38
|
-
File.write(path, JSON.generate(
|
|
39
|
-
"source" => source,
|
|
40
|
-
"target" => target,
|
|
41
|
-
"sha256" => Digest::SHA256.hexdigest(File.binread(target)),
|
|
42
|
-
"mode" => "copy",
|
|
43
|
-
))
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# Sentinel layout: <store_root>/sentinels/<target_rel_to_repo>.textus-managed.json
|
|
47
|
-
# The full target extension is preserved so a marketplace.json and
|
|
48
|
-
# marketplace.yaml don't collide.
|
|
49
|
-
def self.sentinel_path(target, store_root)
|
|
50
|
-
repo_root = File.dirname(store_root)
|
|
51
|
-
rel = relative_to(target, repo_root) || File.basename(target)
|
|
52
|
-
File.join(store_root, SENTINEL_DIR, rel + SENTINEL_SUFFIX)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def self.legacy_sentinel_path(target)
|
|
56
|
-
target + SENTINEL_SUFFIX
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def self.cleanup_legacy_sentinel(target)
|
|
60
|
-
FileUtils.rm_f(legacy_sentinel_path(target))
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def self.relative_to(path, base)
|
|
64
|
-
path = File.expand_path(path)
|
|
65
|
-
base = File.expand_path(base)
|
|
66
|
-
return nil unless path.start_with?(base + File::SEPARATOR)
|
|
67
|
-
|
|
68
|
-
path[(base.length + 1)..]
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
data/lib/textus/store/view.rb
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
module Textus
|
|
2
|
-
class Store
|
|
3
|
-
class View
|
|
4
|
-
READ_METHODS = %i[get list where schema_envelope deps rdeps published stale validate_all].freeze
|
|
5
|
-
WRITE_METHODS = %i[put delete accept].freeze
|
|
6
|
-
|
|
7
|
-
def initialize(store, writable: false, as: nil)
|
|
8
|
-
raise UsageError.new("writable Store::View requires an as: role") if writable && (as.nil? || as.to_s.empty?)
|
|
9
|
-
|
|
10
|
-
@store = store
|
|
11
|
-
@writable = writable
|
|
12
|
-
@as = as
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
READ_METHODS.each do |m|
|
|
16
|
-
define_method(m) { |*args, **kw| @store.reader.public_send(m, *args, **kw) }
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
WRITE_METHODS.each do |m|
|
|
20
|
-
define_method(m) do |*args, **kw|
|
|
21
|
-
raise UsageError.new("Store::View is read-only") unless @writable
|
|
22
|
-
|
|
23
|
-
kw[:as] = @as unless kw.key?(:as)
|
|
24
|
-
@store.public_send(m, *args, **kw)
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|