scout-essentials 1.8.7 → 1.9.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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.vimproject +26 -12
  3. data/README.md +83 -112
  4. data/VERSION +1 -1
  5. data/doc/Improvements.md +226 -0
  6. data/doc/StartHere.md +122 -0
  7. data/doc/developer/AnnotationSystem.md +184 -0
  8. data/doc/developer/Architecture.md +147 -0
  9. data/doc/developer/Configuration.md +238 -0
  10. data/doc/developer/CoreUtilities.md +265 -0
  11. data/doc/developer/DesignPrinciples.md +129 -0
  12. data/doc/developer/ErrorHandling.md +203 -0
  13. data/doc/developer/LockingAndConcurrency.md +157 -0
  14. data/doc/developer/PathResolution.md +200 -0
  15. data/doc/developer/PersistenceAndResources.md +119 -0
  16. data/doc/developer/StreamingModel.md +236 -0
  17. data/doc/user/AnnotatingData.md +202 -0
  18. data/doc/user/CachingResults.md +183 -0
  19. data/doc/user/CommandLineOptions.md +189 -0
  20. data/doc/user/Cookbook.md +211 -0
  21. data/doc/user/HandlingStreams.md +236 -0
  22. data/doc/user/LoggingAndProgress.md +158 -0
  23. data/doc/user/ProducingResources.md +177 -0
  24. data/doc/user/RemoteData.md +157 -0
  25. data/doc/user/RunningCommands.md +218 -0
  26. data/doc/user/WorkingWithFiles.md +217 -0
  27. data/lib/scout/cmd.rb +343 -40
  28. data/lib/scout/concurrent_stream.rb +14 -1
  29. data/lib/scout/indiferent_hash.rb +1 -1
  30. data/lib/scout/log/fingerprint.rb +13 -8
  31. data/lib/scout/log/progress/report.rb +1 -1
  32. data/lib/scout/log.rb +4 -1
  33. data/lib/scout/misc/digest.rb +6 -5
  34. data/lib/scout/misc/format.rb +24 -0
  35. data/lib/scout/named_array.rb +1 -1
  36. data/lib/scout/open/stream.rb +2 -2
  37. data/lib/scout/open/util.rb +8 -4
  38. data/lib/scout/open.rb +3 -3
  39. data/lib/scout/path/find.rb +3 -2
  40. data/lib/scout/persist.rb +14 -10
  41. data/lib/scout/resource/produce.rb +9 -1
  42. data/research/annotations-data-analysis.md +206 -0
  43. data/research/behavior-probes.md +1925 -0
  44. data/research/commands-streaming-analysis.md +272 -0
  45. data/research/design-philosophy-analysis.md +383 -0
  46. data/research/doc-audit-findings.md +294 -0
  47. data/research/ecosystem-attribution.md +118 -0
  48. data/research/implementation-inventory-core.md +1029 -0
  49. data/research/implementation-inventory-open.md +417 -0
  50. data/research/implementation-inventory-path-persist-resource.md +774 -0
  51. data/research/io-paths-analysis.md +228 -0
  52. data/research/persistence-resources-analysis.md +244 -0
  53. data/research/synthesis-report.md +80 -0
  54. data/scout-essentials.gemspec +37 -15
  55. data/test/scout/open/test_remote.rb +1 -2
  56. data/test/scout/test_cmd.rb +411 -0
  57. metadata +36 -14
  58. data/doc/Annotation.md +0 -352
  59. data/doc/CMD.md +0 -363
  60. data/doc/ConcurrentStream.md +0 -163
  61. data/doc/IndiferentHash.md +0 -240
  62. data/doc/Log.md +0 -235
  63. data/doc/NamedArray.md +0 -174
  64. data/doc/Open.md +0 -331
  65. data/doc/Path.md +0 -217
  66. data/doc/Persist.md +0 -214
  67. data/doc/Resource.md +0 -229
  68. data/doc/SimpleOPT.md +0 -236
  69. data/doc/TmpFile.md +0 -154
data/doc/Annotation.md DELETED
@@ -1,352 +0,0 @@
1
- # Annotation
2
-
3
- The Annotation module provides a lightweight system for adding typed, named "annotations" (simple instance variables with accessors) to arbitrary Ruby objects and arrays. It's used by defining annotation modules (modules that `extend Annotation` and declare attributes via `annotation`) and then applying those annotation modules to objects at runtime.
4
-
5
- Key features:
6
- - Define annotation modules with named attributes.
7
- - Attach annotation modules to objects or arrays (including Strings, Arrays, Hashes, Procs, etc.).
8
- - Annotated arrays (`AnnotatedArray`) propagate annotations to their items and provide annotation-aware iteration and collection operations.
9
- - Support for serialization (Marshal) and a `purge` operation that strips annotations from objects (recursively for arrays and hashes).
10
-
11
- ---
12
-
13
- ## Creating an annotation module
14
-
15
- Define a module and `extend Annotation`. Declare annotation attributes using `annotation :attr1, :attr2`.
16
-
17
- Example:
18
-
19
- ```ruby
20
- module MyAnnotation
21
- extend Annotation
22
- annotation :code, :note
23
- end
24
- ```
25
-
26
- When a module is created this way, it gets:
27
- - an internal `@annotations` list (names of attributes),
28
- - accessors for declared attributes (e.g. `code`, `code=`),
29
- - the ability to be used to annotate objects (`MyAnnotation.setup(obj, ...)` or by `obj.extend MyAnnotation`).
30
-
31
- ---
32
-
33
- ## Applying annotations
34
-
35
- Use `Annotation.setup` or the annotation module's `setup` to attach annotations to objects.
36
-
37
- Basic usage:
38
-
39
- - Annotation.setup with a single annotation module:
40
- ```ruby
41
- Annotation.setup(obj, MyAnnotation, code: "X")
42
- ```
43
- or
44
- ```ruby
45
- MyAnnotation.setup(obj, code: "X")
46
- ```
47
-
48
- - Annotation.setup accepts annotation types as:
49
- - a Module constant (e.g. `MyAnnotation`),
50
- - an Array of modules (`[A, B]`),
51
- - a String of module names separated by `|` (will be constantized).
52
-
53
- - The `annotation_hash` (values for attributes) can be:
54
- - a Hash mapping attribute name => value,
55
- - a list of positional values that are zipped with the declared attribute names,
56
- - a Hash with string keys (converted to symbols).
57
- Examples:
58
- ```ruby
59
- MyAnnotation.setup(obj, :code) # sets first attribute to :code (positional)
60
- MyAnnotation.setup(obj, code: "some text") # sets code => "some text"
61
- MyAnnotation.setup(obj, "code" => "v") # string keys are accepted
62
- MyAnnotation.setup(obj, code2: :code) # remap behavior (see examples below)
63
- ```
64
-
65
- - `Annotation.setup` convenience:
66
- ```ruby
67
- # Apply one or more annotation modules
68
- Annotation.setup(obj, [MyAnnotation, OtherAnnotation], code: "c", code3: "d")
69
- ```
70
-
71
- Notes on calling `AnnotationModule.setup` (the module-level setup method used by both `Annotation.setup` and `AnnotationModule.setup`):
72
- - If the target `obj` is frozen, it will be duplicated before extending.
73
- - If a block is passed or `obj` is `nil` and a block is provided, the block (Proc) itself will be annotated (useful to attach annotations to callbacks).
74
- - When multiple modules are applied to the same object, their annotations are merged; accessors are available for all annotated attributes.
75
-
76
- Examples from tests:
77
- ```ruby
78
- str = "String"
79
- MyAnnotation.setup(str, :code)
80
- # now str responds to `code` and `code` == :code
81
- ```
82
-
83
- You can annotate other objects using an annotated object:
84
- ```ruby
85
- a = MyAnnotation.setup("a", code: "c")
86
- b = "b"
87
- a.annotate(b) # copies the annotation values and types from a to b
88
- ```
89
-
90
- ---
91
-
92
- ## Annotated object API
93
-
94
- When an object is annotated (extended with annotation modules), it gains these helpers (provided by `Annotation::AnnotatedObject`):
95
-
96
- - `annotation_types` -> Array of annotation modules applied to the object.
97
- - `annotation_hash` -> Hash mapping annotation attribute names (symbols) to values stored on the object.
98
- - `annotation_info` -> combines `annotation_hash` plus:
99
- - `annotation_types` (modules list),
100
- - `annotated_array` boolean (true when object is an `AnnotatedArray`).
101
- - `.serialize` (instance) and `AnnotatedObject.serialize(obj)` (class method) -> returns a purged `annotation_info` merged with a `literal: obj` entry (useful when creating stable representations).
102
- - `annotation_id` / `id` -> deterministic digest built from the object and its annotation info (uses `Misc.digest` in the framework).
103
- - `annotate(other)` -> applies all annotation types and attribute values of `self` onto `other`.
104
- - `purge` -> returns a duplicate of the object with all annotation-related instance variables removed (`@annotations`, `@annotation_types`, `@container`).
105
- - `make_array` -> returns a new array containing the object, annotated with the same annotation types/values, and extended as an `AnnotatedArray`.
106
-
107
- Example:
108
- ```ruby
109
- s = MyAnnotation.setup("s", code: "C")
110
- s.annotation_hash # => { code: "C" }
111
- s.id # => some digest
112
- s2 = "other"
113
- s.annotate(s2)
114
- s2.code # => "C"
115
- ```
116
-
117
- ---
118
-
119
- ## Annotated arrays (AnnotatedArray)
120
-
121
- `AnnotatedArray` is an array mixin that:
122
- - stores annotation types/values at the array level,
123
- - automatically annotates elements when they are accessed or iterated,
124
- - provides container tracking on items: annotated items get `container` and `container_index` attributes (via `AnnotatedArrayItem`).
125
-
126
- To make an array annotation-aware:
127
- ```ruby
128
- AnnotationModule.setup(ary, code: "C")
129
- ary.extend AnnotatedArray
130
- ```
131
-
132
- Behavior and methods:
133
- - Element access ([], first, last) returns annotated elements (unless `clean = true` passed to `[]`).
134
- - `each`, `each_with_index`, `select`, `inject`, `collect` iterate over annotated items (so blocks receive annotated items).
135
- - `compact`, `uniq`, `flatten`, `reverse`, `sort_by` are overridden to return annotated arrays (the result is annotated and extended with `AnnotatedArray`).
136
- - `subset(list)` and `remove(list)` return new annotated arrays representing the set intersection/difference.
137
- - Annotated array items receive `container` (the array) and `container_index` (the index position when produced via iteration/access).
138
-
139
- Examples:
140
- ```ruby
141
- ary = ["x"]
142
- MyAnnotation.setup(ary, "C")
143
- ary.extend AnnotatedArray
144
-
145
- ary.code # => "C" (array-level)
146
- ary[0].code # => "C" (element annotated)
147
- ary.first.code # => "C"
148
- ary.each { |e| puts e.code } # iterates annotated elements
149
- ```
150
-
151
- `AnnotatedArrayItem` helpers:
152
- - `container` -> reference to the array that annotated the item.
153
- - `container_index` -> index position supplied by the array when returning that item.
154
-
155
- Utility:
156
- - `AnnotatedArray.is_contained?(obj)` -> true if obj is annotated as an `AnnotatedArrayItem`.
157
-
158
- ---
159
-
160
- ## Serialization and Marshal support
161
-
162
- Annotations are stored as instance variables on the annotated objects; thus, `Marshal.dump` / `Marshal.load` preserve annotations and attribute values.
163
-
164
- Example (from tests):
165
- ```ruby
166
- a = MyAnnotation.setup("a", code: 'test1', code2: 'test2')
167
- serialized = Marshal.dump(a)
168
- a2 = Marshal.load(serialized)
169
- a2.code # => 'test1'
170
- ```
171
-
172
- Arrays extended with `AnnotatedArray` and annotated likewise survive Marshal roundtrip; loaded arrays still annotate their elements.
173
-
174
- ---
175
-
176
- ## Purging annotations
177
-
178
- - AnnotatedObject#purge removes annotation instance variables from the object and returns a dup without annotations (`@annotations`, `@annotation_types`, `@container`).
179
- - Annotation.purge(obj) is recursive:
180
- - If obj is nil => returns nil.
181
- - If obj is an annotated array => calls the object's purge and then purges each element recursively.
182
- - If obj is an Array => returns an Array where each element is purged.
183
- - If obj is a Hash => returns a new Hash with purged keys and values.
184
- - Otherwise, if object is annotated (`Annotation.is_annotated?(obj)`), returns `obj.purge`, else returns the object itself.
185
-
186
- Example:
187
- ```ruby
188
- ary = ["string"]
189
- MyAnnotation.setup(ary, "C")
190
- ary.extend AnnotatedArray
191
-
192
- Annotation.is_annotated?(ary) # => true
193
- Annotation.is_annotated?(ary.first) # => true
194
-
195
- purged = Annotation.purge(ary)
196
- Annotation.is_annotated?(purged) # => false
197
- Annotation.is_annotated?(purged.first) # => false
198
- ```
199
-
200
- ---
201
-
202
- ## Detection helpers
203
-
204
- - `Annotation.is_annotated?(obj)` -> true if the object has been annotated (the object has an `@annotation_types` instance variable).
205
- - `AnnotatedArray.is_contained?(obj)` -> true if object is an `AnnotatedArrayItem`.
206
-
207
- ---
208
-
209
- ## Extending and composing annotations
210
-
211
- - Multiple annotation modules can be applied to the same object. Their attributes and values are merged on the object.
212
- - Annotation modules may `include` other annotation modules. When a module including another annotation module is itself extended into an object, the included module's declared attributes are propagated.
213
- - When a module `extend Annotation`, the `Annotation.extended` hook ensures:
214
- - `@annotations` is initialized,
215
- - the module includes `Annotation::AnnotatedObject` (so annotated objects get object helpers),
216
- - the module extends `Annotation::AnnotationModule` (which implements `annotation`, `setup`, and include/extend integration code).
217
-
218
- Example of composing annotations:
219
- ```ruby
220
- module A
221
- extend Annotation
222
- annotation :a1
223
- end
224
-
225
- module B
226
- extend Annotation
227
- annotation :b1
228
- end
229
-
230
- obj = "s"
231
- Annotation.setup(obj, [A, B], a1: 'one', b1: 'two')
232
- # obj now responds to a1, b1
233
- ```
234
-
235
- ---
236
-
237
- ## Notes and edge cases
238
-
239
- - `Annotation.setup(obj, ...)` returns `nil` immediately if `obj.nil?`.
240
- - If the target object is frozen, the setup will duplicate it before extending.
241
- - `AnnotationModule.setup` can accept positional values (zipped with the declared attributes) or a hash mapping attribute names to values.
242
- - Example: `MyModule.setup(obj, :val_for_first)` sets the first declared attribute to `:val_for_first`.
243
- - Example: `MyModule.setup(obj, :a => 1, :b => 2)` sets attributes by name.
244
- - You can annotate a block/proc by passing a block to `setup` (or passing `nil` as the object and supplying a block). The block (Proc) will be extended with the annotation module.
245
- - `Annotation.setup` accepts a third argument (`annotation_hash`) or positional values similar to the module-level `setup`. It also accepts `annotation_types` as a string with `|` separated module names, an Array of modules, or a single module.
246
-
247
- ---
248
-
249
- ## API quick reference
250
-
251
- Annotation module-level:
252
- - Annotation.setup(obj, annotation_types, annotation_hash_or_positional_values)
253
- - obj: object to annotate (String, Array, Array instance, Proc, etc.)
254
- - annotation_types: Module, String (module names separated by `|`), or Array of modules
255
- - annotation_hash_or_positional_values: Hash or positional values mapped to declared attributes
256
- - returns the annotated object (or nil if obj.nil?)
257
-
258
- - Annotation.extended(base) (internal hook) — prepares modules that `extend Annotation`.
259
- - Annotation.is_annotated?(obj) -> boolean
260
- - Annotation.purge(obj) -> returns object or a purged (annotation-free) copy/structure
261
-
262
- Annotation::AnnotationModule (module methods available on modules that `extend Annotation`):
263
- - annotation(*attrs) -> declare attributes and create accessors
264
- - annotations -> declared attributes list
265
- - included(mod) — when the annotation module is included in another module, merges declared attributes
266
- - extended(obj) — when the annotation module is extended into an object, sets up `@annotations` and registers this module into the object's `annotation_types`
267
- - setup(obj, *values_or_hash, &block) -> annotate `obj` (or block) with this module and set attribute values
268
-
269
- Annotation::AnnotatedObject (instance methods added to annotated objects):
270
- - annotation_types -> array of modules applied
271
- - annotation_hash -> Hash of attribute names => values
272
- - annotation_info -> combines annotation_hash + metadata
273
- - serialize / AnnotatedObject.serialize(obj) -> purged annotation_info merged with literal
274
- - annotation_id / id -> digest based id
275
- - annotate(other) -> copy annotations onto `other`
276
- - purge -> duplicate object and remove annotation instance variables
277
- - make_array -> wrap object into annotated array
278
-
279
- AnnotatedArray (array-level helpers):
280
- - extend AnnotatedArray to annotate arrays and propagate annotations to their items
281
- - annotate_item(obj, position = nil) -> annotate an item and set container/container_index
282
- - [] (overridden), first, last, each, each_with_index, select, inject, collect, compact, uniq, flatten, reverse, sort_by, subset, remove
283
-
284
- ---
285
-
286
- ## Examples (from tests)
287
-
288
- Define annotation modules:
289
-
290
- ```ruby
291
- module AnnotationClass
292
- extend Annotation
293
- annotation :code, :code2
294
- end
295
-
296
- module AnnotationClass2
297
- extend Annotation
298
- annotation :code3, :code4
299
- end
300
- ```
301
-
302
- Annotate a string:
303
-
304
- ```ruby
305
- str = "String"
306
- AnnotationClass.setup(str, :code) # sets str.code == :code
307
- AnnotationClass2.setup(str, :c3, :c4)
308
- # str now includes both annotation modules and has code/code2/code3/code4
309
- ```
310
-
311
- Annotate arrays and propagate to elements:
312
-
313
- ```ruby
314
- ary = ["string"]
315
- AnnotationClass.setup(ary, "Annotation String")
316
- ary.extend AnnotatedArray
317
- ary.code # => "Annotation String"
318
- ary[0].code # => "Annotation String"
319
- ary.first.code # => "Annotation String"
320
- ```
321
-
322
- Purge annotations:
323
-
324
- ```ruby
325
- ary = ["string"]
326
- AnnotationClass.setup(ary, "C")
327
- ary.extend AnnotatedArray
328
-
329
- purged = Annotation.purge(ary)
330
- # purged and purged.first are not annotated anymore
331
- ```
332
-
333
- Marshal roundtrip preserves annotations:
334
-
335
- ```ruby
336
- a = AnnotationClass.setup("a", code: 'test1', code2: 'test2')
337
- d = Marshal.dump(a)
338
- a2 = Marshal.load(d)
339
- a2.code # => 'test1'
340
- ```
341
-
342
- Annotating a block:
343
-
344
- ```ruby
345
- # annotate the block (proc) itself
346
- proc_obj = AnnotationClass.setup(nil, code: :c) do
347
- puts "hello"
348
- end
349
- proc_obj.code # => :c
350
- ```
351
-
352
- This document covers the primary use and behaviors of Annotation, the annotation modules that extend it, the AnnotatedObject helpers added to annotated objects, and the AnnotatedArray behaviors. Use the examples above as templates to create, combine, and apply annotations to objects and collections.