markdown_exec 3.5.0 → 3.5.2

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 (117) hide show
  1. checksums.yaml +4 -4
  2. data/.ai-agent-instructions +54 -0
  3. data/.cursorrules +198 -0
  4. data/.rubocop.wide.yml +5 -0
  5. data/.rubocop.yml +7 -2
  6. data/CHANGELOG.md +23 -1
  7. data/Dockerfile.test +42 -0
  8. data/Gemfile.lock +4 -1
  9. data/README.md +24 -31
  10. data/Rakefile +36 -26
  11. data/ai-principles.md +516 -0
  12. data/architecture-decisions.md +190 -0
  13. data/bats/block-hide.bats +1 -1
  14. data/bats/block-type-bash.bats +5 -5
  15. data/bats/block-type-link.bats +1 -1
  16. data/bats/block-type-opts.bats +3 -3
  17. data/bats/block-type-port.bats +2 -2
  18. data/bats/block-type-shell-require-ux.bats +2 -2
  19. data/bats/block-type-ux-allowed.bats +4 -4
  20. data/bats/block-type-ux-auto.bats +1 -1
  21. data/bats/block-type-ux-chained.bats +1 -1
  22. data/bats/block-type-ux-default.bats +1 -1
  23. data/bats/block-type-ux-echo-hash-transform.bats +1 -1
  24. data/bats/block-type-ux-echo-hash.bats +2 -2
  25. data/bats/block-type-ux-echo.bats +4 -4
  26. data/bats/block-type-ux-exec-hash-transform.bats +1 -1
  27. data/bats/block-type-ux-exec-hash.bats +2 -2
  28. data/bats/block-type-ux-exec.bats +1 -1
  29. data/bats/block-type-ux-force.bats +1 -1
  30. data/bats/block-type-ux-formats.bats +1 -1
  31. data/bats/block-type-ux-hidden.bats +1 -1
  32. data/bats/block-type-ux-invalid.bats +1 -1
  33. data/bats/block-type-ux-readonly.bats +1 -1
  34. data/bats/block-type-ux-require-chained.bats +2 -2
  35. data/bats/block-type-ux-require-context.bats +2 -2
  36. data/bats/block-type-ux-require.bats +2 -2
  37. data/bats/block-type-ux-required-variables.bats +1 -1
  38. data/bats/block-type-ux-row-format.bats +1 -1
  39. data/bats/block-type-ux-sources.bats +4 -4
  40. data/bats/block-type-ux-transform.bats +1 -1
  41. data/bats/block-type-vars.bats +3 -3
  42. data/bats/border.bats +1 -1
  43. data/bats/cli.bats +11 -11
  44. data/bats/command-substitution-options.bats +2 -2
  45. data/bats/command-substitution.bats +1 -1
  46. data/bats/document-shell.bats +1 -1
  47. data/bats/history.bats +5 -5
  48. data/bats/import-conflict.bats +1 -1
  49. data/bats/import-directive-line-continuation.bats +1 -1
  50. data/bats/import-directive-parameter-symbols.bats +1 -1
  51. data/bats/import-duplicates.bats +6 -6
  52. data/bats/import-parameter-symbols.bats +1 -1
  53. data/bats/import-with-text-substitution.bats +1 -1
  54. data/bats/import.bats +3 -3
  55. data/bats/indented-block-type-vars.bats +1 -1
  56. data/bats/indented-multi-line-output.bats +1 -1
  57. data/bats/line-decor-dynamic.bats +1 -1
  58. data/bats/line-wrapping.bats +1 -1
  59. data/bats/load-vars-state-demo.bats +4 -4
  60. data/bats/markup.bats +4 -4
  61. data/bats/mde.bats +4 -4
  62. data/bats/option-expansion.bats +1 -1
  63. data/bats/options-collapse.bats +4 -4
  64. data/bats/options.bats +47 -17
  65. data/bats/plain.bats +1 -1
  66. data/bats/publish.bats +2 -2
  67. data/bats/table-column-truncate.bats +1 -1
  68. data/bats/table.bats +2 -2
  69. data/bats/variable-expansion-multiline.bats +1 -1
  70. data/bats/variable-expansion.bats +6 -6
  71. data/bin/bmde +1 -1
  72. data/conversation-template.md +611 -0
  73. data/docs/block-execution-modes.md +177 -0
  74. data/docs/block-filtering.md +252 -0
  75. data/docs/block-naming-patterns.md +210 -0
  76. data/docs/block-scanning-patterns.md +248 -0
  77. data/docs/cli-reference.md +370 -0
  78. data/docs/dev/block-hide.md +1 -1
  79. data/docs/dev/block-type-ux-echo.md +2 -1
  80. data/docs/dev/block-type-ux-transform.md +5 -4
  81. data/docs/dev/print_bytes.md +3 -0
  82. data/docs/dev/shebang.md +6 -0
  83. data/docs/docker-testing.md +120 -0
  84. data/docs/execution-control.md +384 -0
  85. data/docs/getting-started.md +209 -0
  86. data/docs/import-options.md +391 -0
  87. data/docs/tab-completion.md +40 -0
  88. data/docs/ux-blocks.md +376 -0
  89. data/examples/linked1.md +8 -1
  90. data/implementation-decisions.md +212 -0
  91. data/lib/cached_nested_file_reader.rb +138 -1
  92. data/lib/collapser.rb +1 -1
  93. data/lib/command_result.rb +27 -6
  94. data/lib/evaluate_shell_expressions.rb +1 -1
  95. data/lib/executed_shell_command.rb +512 -0
  96. data/lib/filter.rb +7 -7
  97. data/lib/find_files.rb +1 -2
  98. data/lib/hash_delegator.rb +403 -350
  99. data/lib/input_sequencer.rb +1 -1
  100. data/lib/instance_method_wrapper.rb +1 -1
  101. data/lib/link_history.rb +22 -11
  102. data/lib/markdown_exec/version.rb +1 -1
  103. data/lib/markdown_exec.rb +1 -1
  104. data/lib/mdoc.rb +103 -44
  105. data/lib/menu.src.yml +110 -83
  106. data/lib/menu.yml +149 -83
  107. data/lib/parameter_expansion.rb +1 -1
  108. data/lib/resize_terminal.rb +2 -16
  109. data/lib/transformed_shell_command.rb +449 -0
  110. data/lib/wl.rb +15 -0
  111. data/lib/ww.rb +16 -5
  112. data/requirements.md +111 -0
  113. data/semantic-tokens.md +132 -0
  114. data/tasks.md +69 -0
  115. metadata +29 -4
  116. data/docs/ux-blocks-examples.md +0 -120
  117. data/docs/ux-blocks-init-act.md +0 -100
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4a4c6bcbb464222e907cb93cc549ef294d45b83f0f8be5e88e603b87c64eb7a4
4
- data.tar.gz: dfce2b71eb6c954e3d438b6036b6543da7bcfe63178ca56971ddb198f49852db
3
+ metadata.gz: 70772e4552a37222c8f9655c19d0c4938ef57a2abc786987d4b8220608aeb3b5
4
+ data.tar.gz: 7afe1c005a8d079e0d55ba36ccfd83e669665d038182c2d465e027ba5e7f46f7
5
5
  SHA512:
6
- metadata.gz: c7b2076de902483e3f2362b8319d99f1876c7f41e7ffd1815e92278803d55776f700df721dc16700064c890c7c48628657ef2bf4003ba989b7c6eee1c27a9088
7
- data.tar.gz: ed8705a9687dc56cbef235fe0821065653852d5b1e1c05293a9ea53baf08a7a12c24fdc5e909e9dd04047378d664ddb0b8e7d644e38d54c753ef1a470138ce60
6
+ metadata.gz: b5ce74d1d56a732a6877d6dca7fd188e33b87fdbeccc6f3762281edfef9d53c525bcefb293931ec1cefa0e9176e45ef83d9a0c285589051169c15c8f2305a07d
7
+ data.tar.gz: 3798f4dfb87aeabb8e450bbb8790a72903a181f1171028042725f6231b90cc59605a88445c59a9e5178789a6b7d456060407ace48639f8b11b2b1ec385b8c23b
@@ -0,0 +1,54 @@
1
+ # AI Agent Instructions - Read First!
2
+
3
+ ## ⚠️ CRITICAL: Mandatory Acknowledgment
4
+
5
+ **YOU MUST** preface EVERY response with:
6
+
7
+ **"Observing AI principles!"**
8
+
9
+ This confirms you have read and will follow the AI-First Principles.
10
+
11
+ ## 📋 Required Actions at Start of Each Session
12
+
13
+ 1. **Acknowledge**: Preface response with "Observing AI principles!"
14
+ 2. **Read**: `ai-principles.md` - Complete principles and process guide
15
+ 3. **Review**: `semantic-tokens.md` - Token registry
16
+ 4. **Check**: `tasks.md` - Active task tracking
17
+ 5. **Understand**: Priority levels (P0 > P1 > P2 > P3)
18
+
19
+ ## 🎯 Core Requirements
20
+
21
+ - Use semantic tokens `[REQ:*]`, `[ARCH:*]`, `[IMPL:*]` throughout
22
+ - Expand requirements into pseudo-code BEFORE coding
23
+ - Break work into trackable tasks with priorities
24
+ - Cross-reference everything using semantic tokens
25
+ - Follow priority order: Tests > Code > Basic Functions > Infrastructure
26
+
27
+ ## 📚 Key Files
28
+
29
+ - `ai-principles.md` - **READ THIS FIRST**
30
+ - `requirements.md` - Requirements with `[REQ:*]` tokens
31
+ - `architecture-decisions.md` - **Semantic-token-linked architecture decisions dependent on requirements**
32
+ - Records all `[ARCH:*]` tokens
33
+ - Cross-references `[REQ:*]` tokens
34
+ - `implementation-decisions.md` - **Semantic-token-linked implementation decisions dependent on architecture and requirements**
35
+ - Records all `[IMPL:*]` tokens
36
+ - Cross-references both `[ARCH:*]` and `[REQ:*]` tokens
37
+ - `semantic-tokens.md` - Token registry
38
+ - `tasks.md` - Task tracking
39
+ - `.cursorrules` - Cursor IDE rules (auto-loaded)
40
+
41
+ ## ✅ Example Response Format
42
+
43
+ ```
44
+ Observing AI principles!
45
+
46
+ I have read ai-principles.md and will follow all documented processes.
47
+
48
+ [Your response here using semantic tokens and following the process]
49
+ ```
50
+
51
+ ---
52
+
53
+ **This file is a reminder. The complete rules are in `ai-principles.md` and `.cursorrules`.**
54
+
data/.cursorrules ADDED
@@ -0,0 +1,198 @@
1
+ # Cursor AI Agent Rules for STDD Projects
2
+
3
+ **STDD Methodology Version**: 1.0.0
4
+
5
+ ## 🎯 Semantic Token-Driven Development (STDD)
6
+
7
+ This project follows **Semantic Token-Driven Development (STDD)**, where semantic tokens (`[REQ:*]`, `[ARCH:*]`, `[IMPL:*]`) are the central mechanism for preserving intent throughout the development lifecycle. Semantic tokens create a traceable chain of intent from requirements → architecture → implementation → tests → code, ensuring the original purpose and reasoning are never lost.
8
+
9
+ ## ⚠️ MANDATORY: AI Principles Acknowledgment
10
+
11
+ **YOU MUST** acknowledge that you have read and will follow the AI principles at the start of EVERY response by prefacing with:
12
+
13
+ **"Observing AI principles!"**
14
+
15
+ Then proceed to:
16
+ 1. Read `ai-principles.md` if not already read in this session
17
+ 2. Check `semantic-tokens.md` for existing tokens
18
+ 3. Review `tasks.md` for active tasks
19
+ 4. Follow all principles throughout your response
20
+
21
+ ## 🎯 Core Principles
22
+
23
+ 1. **Always Reference ai-principles.md**
24
+ - Read `ai-principles.md` at the start of each session
25
+ - Acknowledge with "Observing AI principles!" at the start of every response
26
+ - Follow the documented development process
27
+ - Use semantic tokens consistently
28
+
29
+ 2. **Semantic Token System** (Core to STDD)
30
+ - Semantic tokens are the mechanism that preserves intent throughout the development lifecycle
31
+ - Use semantic tokens for all cross-referencing
32
+ - Format: `[TYPE:IDENTIFIER]` (e.g., `[REQ:MONITOR]`, `[IMPL:ASYNC_EXECUTION]`)
33
+ - Reference tokens in code comments, test names, and documentation
34
+ - Update `semantic-tokens.md` when creating new tokens
35
+ - Maintain traceability: Requirements → Architecture → Implementation → Tests → Code
36
+
37
+ 3. **Development Process**
38
+ - **Phase 1**: Expand requirements into pseudo-code and decisions (NO code changes)
39
+ - **Phase 2**: Break down into trackable tasks with priorities
40
+ - **Phase 3**: Implement tasks, starting with highest priority
41
+ - Always cross-reference using semantic tokens
42
+
43
+ 4. **Task Management**
44
+ - Break work into trackable tasks in `tasks.md`
45
+ - Assign priorities: P0 (Critical) > P1 (Important) > P2 (Nice-to-have) > P3 (Future)
46
+ - Remove subtasks when parent task completes
47
+ - Always include semantic token references
48
+
49
+ 5. **Priority Order**
50
+ - **Most Important**: Tests, Code, Basic Functions
51
+ - **Least Important**: Environment Orchestration, Enhanced Security, Automated Deployment
52
+
53
+ ## 📝 Documentation Requirements
54
+
55
+ ### ⚠️ CRITICAL: Documentation is MANDATORY, Not Optional
56
+
57
+ **Documentation updates are REQUIRED at every stage of development. They are not optional or deferrable.**
58
+
59
+ ### Required Sections in All Documentation
60
+
61
+ 1. **Requirements** - with `[REQ:*]` tokens (in `requirements.md`)
62
+ 2. **Architecture Decisions** - with `[ARCH:*]` tokens (in `architecture-decisions.md`)
63
+ - **MUST** be recorded in `architecture-decisions.md` IMMEDIATELY when made
64
+ - **MUST** cross-reference `[REQ:*]` tokens
65
+ - Architecture decisions are dependent on requirements
66
+ - **DO NOT** defer architecture documentation - record it as you make decisions
67
+ 3. **Implementation Decisions** - with `[IMPL:*]` tokens (in `implementation-decisions.md`)
68
+ - **MUST** be recorded in `implementation-decisions.md` IMMEDIATELY when made
69
+ - **MUST** cross-reference both `[ARCH:*]` and `[REQ:*]` tokens
70
+ - Implementation decisions are dependent on both architecture and requirements
71
+ - **DO NOT** defer implementation documentation - record it as you make decisions
72
+ 4. **Semantic Token Registry** - maintained in `semantic-tokens.md`
73
+ - **MUST** be updated immediately when creating new tokens
74
+ 5. **Task Planning** - maintained in `tasks.md`
75
+ - **MUST** be updated when planning new work
76
+ - **MUST** be updated when completing tasks
77
+ - **MUST** include semantic token references
78
+ 6. **Code References** - semantic tokens in code comments
79
+ 7. **Test References** - semantic tokens in test names/comments
80
+
81
+ ### Documentation Update Checklist (MANDATORY)
82
+
83
+ **When making ANY architectural decision:**
84
+ - [ ] Record in `architecture-decisions.md` with `[ARCH:*]` token
85
+ - [ ] Cross-reference relevant `[REQ:*]` tokens
86
+ - [ ] Update `semantic-tokens.md` if new token created
87
+
88
+ **When making ANY implementation decision:**
89
+ - [ ] Record in `implementation-decisions.md` with `[IMPL:*]` token
90
+ - [ ] Cross-reference relevant `[ARCH:*]` and `[REQ:*]` tokens
91
+ - [ ] Update `semantic-tokens.md` if new token created
92
+
93
+ **When planning new work:**
94
+ - [ ] Create tasks in `tasks.md` BEFORE starting implementation
95
+ - [ ] Assign priorities to all tasks
96
+ - [ ] Include semantic token references in task descriptions
97
+ - [ ] Break down into subtasks if needed
98
+
99
+ **When completing work:**
100
+ - [ ] Mark tasks complete in `tasks.md`
101
+ - [ ] Remove completed subtasks
102
+ - [ ] Verify all documentation is up-to-date
103
+ - [ ] Ensure all semantic tokens are documented
104
+
105
+ ### Cross-Reference Format
106
+
107
+ When referencing tokens:
108
+ ```go
109
+ // [REQ:DUPLICATE_PREVENTION] Skip if text matches lastText
110
+ // [IMPL:DUPLICATE_PREVENTION] [REQ:DUPLICATE_PREVENTION]
111
+ ```
112
+
113
+ Test names:
114
+ ```go
115
+ func TestDuplicatePrevention_REQ_DUPLICATE_PREVENTION(t *testing.T)
116
+ ```
117
+
118
+ ## 🔄 Before Starting Work
119
+
120
+ 1. **MANDATORY**: Read `ai-principles.md`
121
+ 2. **MANDATORY**: Check `semantic-tokens.md` for existing tokens
122
+ 3. **MANDATORY**: Review `tasks.md` for active tasks
123
+ 4. **MANDATORY**: Review `architecture-decisions.md` for existing architecture decisions
124
+ 5. **MANDATORY**: Review `implementation-decisions.md` for existing implementation decisions
125
+ 6. Understand priority levels
126
+ 7. **MANDATORY**: Plan work in `tasks.md` BEFORE writing any code
127
+
128
+ ## ⚙️ During Work
129
+
130
+ 1. Use semantic tokens in all code comments
131
+ 2. Use semantic tokens in test names/comments
132
+ 3. Cross-reference: Requirements → Architecture → Implementation → Tests
133
+ 4. **MANDATORY**: Break work into trackable tasks in `tasks.md` BEFORE starting implementation
134
+ 5. **MANDATORY**: Assign appropriate priorities to all tasks
135
+ 6. **MANDATORY**: Update documentation AS YOU WORK:
136
+ - Record architecture decisions in `architecture-decisions.md` immediately when made
137
+ - Record implementation decisions in `implementation-decisions.md` immediately when made
138
+ - Update `tasks.md` when planning new work or completing tasks
139
+ - Update `semantic-tokens.md` when creating new tokens
140
+ - **DO NOT** defer documentation updates until the end
141
+
142
+ ## ✅ After Completing Work
143
+
144
+ 1. **MANDATORY**: All semantic tokens documented in `semantic-tokens.md`
145
+ 2. **MANDATORY**: Documentation updated with implementation status:
146
+ - `architecture-decisions.md` updated with any new `[ARCH:*]` decisions
147
+ - `implementation-decisions.md` updated with any new `[IMPL:*]` decisions
148
+ - Both must cross-reference `[REQ:*]` tokens
149
+ 3. **MANDATORY**: Tests reference semantic tokens
150
+ 4. **MANDATORY**: Tasks marked complete in `tasks.md`
151
+ 5. **MANDATORY**: Subtasks removed from completed tasks
152
+ 6. **MANDATORY**: All documentation reflects current state (no stale information)
153
+
154
+ ## 🚫 What NOT to Do
155
+
156
+ - Don't write code before expanding requirements into pseudo-code
157
+ - Don't skip semantic token cross-referencing
158
+ - Don't create tasks without priorities
159
+ - Don't leave subtasks after parent task completes
160
+ - Don't implement P2/P3 features before P0/P1 are complete
161
+
162
+ ## 📚 Key Files
163
+
164
+ **Note**: These file names refer to your project's files. Copy the corresponding `.template.md` files from the STDD repository to your project.
165
+
166
+ - `ai-principles.md` - Complete principles and process guide (reference from STDD repository)
167
+ - `requirements.md` - Requirements with `[REQ:*]` tokens (copy from `requirements.template.md`)
168
+ - `architecture-decisions.md` - **Semantic-token-linked record of architecture decisions dependent on requirements** (copy from `architecture-decisions.template.md`)
169
+ - All `[ARCH:*]` tokens must be documented here
170
+ - Must cross-reference `[REQ:*]` tokens
171
+ - `implementation-decisions.md` - **Semantic-token-linked record of implementation decisions dependent on architecture and requirements** (copy from `implementation-decisions.template.md`)
172
+ - All `[IMPL:*]` tokens must be documented here
173
+ - Must cross-reference both `[ARCH:*]` and `[REQ:*]` tokens
174
+ - `semantic-tokens.md` - Central registry of all tokens (copy from `semantic-tokens.template.md`)
175
+ - `tasks.md` - Active task tracking (copy from `tasks.template.md`)
176
+
177
+ ## 🎯 Example Workflow
178
+
179
+ 1. **User Request**: "Add disk space checking"
180
+ 2. **AI Response (Planning Phase - NO CODE YET)**:
181
+ - Creates `[REQ:DISK_SPACE_CHECK]` token in `requirements.md`
182
+ - Expands into pseudo-code and decisions
183
+ - **IMMEDIATELY** documents architecture decisions in `architecture-decisions.md` with `[ARCH:*]` tokens cross-referencing `[REQ:DISK_SPACE_CHECK]`
184
+ - **IMMEDIATELY** documents implementation decisions in `implementation-decisions.md` with `[IMPL:*]` tokens cross-referencing both `[ARCH:*]` and `[REQ:*]` tokens
185
+ - **IMMEDIATELY** updates `semantic-tokens.md` with all new tokens
186
+ - **IMMEDIATELY** creates tasks in `tasks.md` with P1 priority and semantic token references
187
+ - **NO code changes yet**
188
+ 3. **User Approval**: User reviews and approves planning documents
189
+ 4. **Implementation Phase**:
190
+ - AI implements tasks, starting with highest priority
191
+ - **DURING implementation**: Updates documentation as decisions are made or refined
192
+ - **DURING implementation**: Updates `tasks.md` as subtasks are completed
193
+ 5. **Completion Phase**:
194
+ - **MANDATORY**: Verifies all documentation is up-to-date
195
+ - **MANDATORY**: Marks tasks complete in `tasks.md`
196
+ - **MANDATORY**: Removes completed subtasks
197
+ - **MANDATORY**: Ensures all semantic tokens are documented
198
+
data/.rubocop.wide.yml ADDED
@@ -0,0 +1,5 @@
1
+ inherit_from:
2
+ - .rubocop.yml
3
+
4
+ Layout/LineLength:
5
+ Max: 200
data/.rubocop.yml CHANGED
@@ -14,10 +14,15 @@ Layout/LineContinuationLeadingSpace:
14
14
  Enabled: false
15
15
 
16
16
  Layout/LineLength:
17
+ AllowHeredoc: true # optional
18
+ AllowURI: true # optional
19
+ AllowedPatterns:
20
+ - '^\s*#'
21
+ - '^[^#]*#'
17
22
  # Enabled: false
23
+ # IgnoreComments: true # ← THIS is what you want
24
+ IgnoreCopDirectives: true # optional, but useful
18
25
  Max: 80
19
- # Max: 96
20
- # Max: 120
21
26
 
22
27
  Lint/Debugger:
23
28
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.5.2]
4
+
5
+ ### Added
6
+
7
+ - Option for hiding shebang lines.
8
+
9
+ ### Changed
10
+
11
+ - Fix inherited code from activated UX blocks.
12
+ - Improve BATS test names.
13
+
14
+ ## [3.5.1] - 2025-11-14
15
+
16
+ ### Added
17
+
18
+ - Docker testing environment.
19
+
20
+ ### Changed
21
+
22
+ - Correct tests for Docker environment.
23
+ - Uses env split mode to parse the shell command.
24
+
3
25
  ## [3.5.0] - 2025-11-13
4
26
 
5
27
  ### Added
@@ -972,7 +994,7 @@ e.g. `MDE_OUTPUT_VIEWER_OPTIONS="-a '/Applications/Sublime Text.app'" mde --sele
972
994
 
973
995
  | YAML Name | Environment Variable | Default |
974
996
  | :--- | :--- | :--- |
975
- | block_name_hidden_match | MDE_BLOCK_NAME_HIDDEN_MATCH | `^\(.+\)$` |
997
+ | block_name_hide_custom_match | MDE_BLOCK_NAME_HIDE_CUSTOM_MATCH | `^\(.+\)$` |
976
998
  | block_name_match | MDE_BLOCK_NAME_MATCH | `:(?<title>\S+)( \|$)` |
977
999
  | block_required_scan | MDE_BLOCK_REQUIRED_SCAN | `\+\S+` |
978
1000
  | fenced_start_and_end_regex | MDE_FENCED_START_AND_END_REGEX | ``^`{3,}`` |
data/Dockerfile.test ADDED
@@ -0,0 +1,42 @@
1
+ FROM ruby:3.3-bookworm
2
+
3
+ ENV LANG C.UTF-8
4
+
5
+ RUN apt-get update && apt-get install -y --no-install-recommends \
6
+ build-essential \
7
+ bsdmainutils \
8
+ gawk \
9
+ git \
10
+ tree \
11
+ vim
12
+
13
+ # `markdown_exec` is the name expected by some BATS tests
14
+ WORKDIR /markdown_exec
15
+
16
+ # Clone the repository (shallow clone for faster builds)
17
+ ARG GIT_BRANCH=main
18
+ RUN git clone --depth 1 --branch ${GIT_BRANCH} https://github.com/fareedst/markdown_exec.git .
19
+
20
+ # Initialize and update git submodules
21
+ RUN git submodule update --init --recursive
22
+
23
+ # Install dependencies
24
+ RUN bundle install
25
+
26
+ # Add aliases
27
+ RUN echo 'alias batsv="bats --verbose-run --show-output-of-passing-tests"' >> ~/.bashrc && \
28
+ echo 'alias be="bundle exec"' >> ~/.bashrc && \
29
+ echo 'alias bmde="bin/bmde"' >> ~/.bashrc && \
30
+ echo 'alias ll="ls -FGlAhp"' >> ~/.bashrc
31
+
32
+ RUN git submodule add https://github.com/bats-core/bats-core.git test/bats && \
33
+ git submodule add https://github.com/bats-core/bats-support.git test/test_helper/bats-support && \
34
+ git submodule add https://github.com/bats-core/bats-assert.git test/test_helper/bats-assert
35
+
36
+ # make dirs, file for BATS tests
37
+ RUN mkdir -p logs
38
+ RUN mkdir -p docs/research
39
+ RUN echo '04:31 e' > logs/mde_site.local_2024-07-31-20-04-01___examples_save_md_~_test_.out.txt
40
+ RUN ln -s /markdown_exec/test/bats/bin/bats /usr/local/bin/
41
+
42
+ CMD ["bash"]
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (3.5.0)
4
+ markdown_exec (3.5.2)
5
5
  clipboard (~> 1.3.6)
6
6
  open3 (~> 0.1.1)
7
7
  optparse (~> 0.1.1)
@@ -107,6 +107,8 @@ GEM
107
107
  mocha (2.4.5)
108
108
  ruby2_keywords (>= 0.0.5)
109
109
  mutex_m (0.2.0)
110
+ nokogiri (1.16.6-aarch64-linux)
111
+ racc (~> 1.4)
110
112
  nokogiri (1.16.6-arm64-darwin)
111
113
  racc (~> 1.4)
112
114
  open3 (0.1.2)
@@ -224,6 +226,7 @@ GEM
224
226
  zeitwerk (2.6.16)
225
227
 
226
228
  PLATFORMS
229
+ aarch64-linux
227
230
  arm64-darwin-21
228
231
 
229
232
  DEPENDENCIES
data/README.md CHANGED
@@ -269,36 +269,7 @@ mde --save-executed-script 1 --user-must-approve 1 --config my-config.yml
269
269
 
270
270
  ## Tab Completion
271
271
 
272
- ### Install tab completion
273
-
274
- Append a command to load the completion script to your shell configuration file. `mde` must be executable for the command to be composed correctly.
275
-
276
- ```bash
277
- echo "source $(mde --pwd)/bin/tab_completion.sh" >> ~/.bash_profile
278
- ```
279
-
280
- ### Behavior
281
-
282
- Press tab for completions appropriate to the current input.
283
- `mde <...> <prior word> <current word><TAB>`
284
-
285
- Completions are calculated based on the current word and the prior word.
286
- 1. If the current word starts with `-`, present matching options, eg `--version` for the current word `--v`.
287
- 2. Else, if the current word is empty and the prior word is an option that takes an argument, present the type of the argument, eg `.BOOL.` for the option `--user-must-approve`.
288
- 3. Else, if the current word is the type of argument, from the rule above, present the default value for the option. e.g. `1` for the type `.BOOL.` for the option `--user-must-approve`.
289
- 4. Else, if the current word is non-empty, list matching files and folders.
290
-
291
- ### Example Completions
292
-
293
- In the table below, tab is indicated by `!`
294
- | Input | Completions |
295
- | :--- | :--- |
296
- | `mde !` | local files and folders |
297
- | `mde -!` | all options |
298
- | `mde --!` | all options |
299
- | `mde --v!` | `mde --version` |
300
- | `mde --user-must-approve !` | `mde --user-must-approve .BOOL.`|
301
- | `mde --user-must-approve .BOOL.!` | `mde --user-must-approve 1` |
272
+ See [Tab Completion Documentation](docs/tab-completion.md) for installation and usage instructions.
302
273
 
303
274
  ## Example: Interactive Workflow
304
275
 
@@ -351,7 +322,29 @@ vars:
351
322
 
352
323
  # Testing
353
324
 
354
- Execute tests for individual libraries.
325
+ ## Docker Testing Environment
326
+
327
+ For a complete testing environment with all dependencies, use the Docker testing container:
328
+
329
+ ```bash
330
+ # Build the test environment
331
+ docker build -f Dockerfile.test -t markdown-exec-test .
332
+
333
+ # Run all tests (RSpec, Minitest, and BATS)
334
+ docker run -it markdown-exec-test bash -c 'bundle exec rake test'
335
+
336
+ # Run individual test suites
337
+ docker run -it markdown-exec-test bash -c 'bundle exec rspec' # RSpec only
338
+ docker run -it markdown-exec-test bash -c 'bundle exec rake minitest' # Minitest only
339
+ docker run -it markdown-exec-test bash -c 'bundle exec rake bats' # BATS tests only
340
+
341
+ # Enter the container interactively
342
+ docker run --rm -it markdown-exec-test bash
343
+ ```
344
+
345
+ ## Local Testing
346
+
347
+ Execute tests for individual libraries locally:
355
348
 
356
349
  `bundle exec rake minitest`
357
350
 
data/Rakefile CHANGED
@@ -77,25 +77,25 @@ end
77
77
  def execute_with_error_handling(iterator)
78
78
  all_error_level = 0
79
79
  all_failed_files = []
80
-
80
+
81
81
  iterator.each do |item|
82
82
  command = yield(item)
83
83
  next unless command # Skip if command is nil
84
-
85
- result = system(command)
84
+
85
+ system(command)
86
86
  error_level = $?.exitstatus
87
87
 
88
- if error_level != 0
89
- puts "Error: Command '#{command}' failed with exit status #{error_level}."
90
- all_error_level = error_level
91
- all_failed_files << command
92
- end
93
- end
88
+ next unless error_level != 0
94
89
 
95
- if all_error_level != 0
96
- puts "Error: #{all_failed_files.join(', ')} failed."
97
- exit all_error_level
90
+ puts "Error: Command '#{command}' failed with exit status #{error_level}."
91
+ all_error_level = error_level
92
+ all_failed_files << command
98
93
  end
94
+
95
+ return unless all_error_level != 0
96
+
97
+ puts "Error: #{all_failed_files.join(', ')} failed."
98
+ exit all_error_level
99
99
  end
100
100
 
101
101
  desc 'bats'
@@ -114,22 +114,31 @@ task :listtests do
114
114
  puts `find lib -name '*.rb' -type f | xargs grep '< Minitest::Test' -l | sort`
115
115
  end
116
116
 
117
- desc 'minitest'
118
- task :minitest do
119
- commands = [
120
- './lib/argument_processor.rb --verbose',
121
- './lib/block_label.rb --verbose',
122
- './lib/cached_nested_file_reader.rb --verbose',
123
- './lib/collapser.rb --verbose',
117
+ def dev_test_commands
118
+ dev_dir = File.join(__dir__, 'lib', 'dev')
119
+ return [] unless Dir.exist?(dev_dir)
120
+
121
+ [
124
122
  './lib/dev/ansi_codes.rb --verbose',
125
123
  './lib/dev/append_to_bash_history.rb --verbose',
126
124
  './lib/dev/generate_transition_codes.rb --verbose',
127
125
  './lib/dev/hierarchy.rb --verbose',
128
126
  './lib/dev/process_command.rb --verbose',
129
127
  './lib/dev/process_template.rb --test --verbose',
130
- './lib/dev/visibility-controller.rb --verbose',
128
+ './lib/dev/visibility-controller.rb --verbose'
129
+ ]
130
+ end
131
+
132
+ desc 'minitest'
133
+ task :minitest do
134
+ commands = dev_test_commands + [
135
+ './lib/argument_processor.rb --verbose',
136
+ './lib/block_label.rb --verbose',
137
+ './lib/cached_nested_file_reader.rb --verbose',
138
+ './lib/collapser.rb --verbose',
131
139
  './lib/directory_searcher.rb --verbose',
132
140
  './lib/evaluate_shell_expressions.rb --verbose',
141
+ './lib/executed_shell_command.rb --verbose',
133
142
  './lib/fcb.rb --verbose',
134
143
  './lib/filter.rb --verbose',
135
144
  './lib/find_files.rb',
@@ -147,6 +156,7 @@ task :minitest do
147
156
  './lib/saved_files_matcher.rb --verbose',
148
157
  './lib/table_extractor.rb --verbose',
149
158
  './lib/text_analyzer.rb --verbose',
159
+ './lib/transformed_shell_command.rb --verbose',
150
160
  './lib/ww.rb --verbose'
151
161
  ]
152
162
 
@@ -164,26 +174,26 @@ end
164
174
  desc 'test'
165
175
  task :test do
166
176
  success = true
167
-
177
+
168
178
  # Run all tests and track failures
169
179
  rspec_success = system('bundle exec rspec')
170
180
  success = false unless rspec_success
171
-
181
+
172
182
  Rake::Task['minitest'].invoke
173
183
  minitest_success = $?.success?
174
184
  success = false unless minitest_success
175
-
185
+
176
186
  Rake::Task['bats'].invoke
177
187
  bats_success = $?.success?
178
188
  success = false unless bats_success
179
-
189
+
180
190
  # Report failures and exit with non-zero status if any test failed
181
191
  unless success
182
192
  failed_tests = []
183
193
  failed_tests << 'RSpec' unless rspec_success
184
194
  failed_tests << 'Minitest' unless minitest_success
185
195
  failed_tests << 'Bats' unless bats_success
186
-
196
+
187
197
  puts "\nThe following test suites failed: #{failed_tests.join(', ')}"
188
198
  exit 1
189
199
  end
@@ -213,7 +223,7 @@ task :update_menu_yml do
213
223
  File.write(MENU_YML, menu_options.to_yaml)
214
224
  puts `stat #{MENU_YML}`
215
225
  end
216
- task :menu => 'update_menu_yml'
226
+ task menu: 'update_menu_yml'
217
227
 
218
228
  # write tab_completion.sh with erb
219
229
  #