expect-pty 0.5.3 → 0.7.1

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -1
  3. data/README.md +122 -130
  4. data/docs/API.md +113 -0
  5. data/docs/MIGRATION.md +68 -0
  6. data/lib/expect/cleanup.rb +34 -0
  7. data/lib/expect/interaction.rb +228 -210
  8. data/lib/expect/logging.rb +117 -162
  9. data/lib/expect/matcher.rb +42 -38
  10. data/lib/expect/pattern.rb +10 -3
  11. data/lib/expect/pattern_list.rb +39 -9
  12. data/lib/expect/redactor.rb +12 -5
  13. data/lib/expect/relay.rb +106 -81
  14. data/lib/expect/relay_writer.rb +7 -5
  15. data/lib/expect/result.rb +33 -9
  16. data/lib/expect/session.rb +554 -0
  17. data/lib/expect/session_resources.rb +19 -18
  18. data/lib/expect/version.rb +2 -2
  19. data/lib/expect.rb +68 -578
  20. data/sig/expect.rbs +279 -0
  21. metadata +14 -123
  22. data/.rubocop.yml +0 -66
  23. data/CONTRIBUTING.md +0 -29
  24. data/Gemfile +0 -28
  25. data/Rakefile +0 -38
  26. data/benchmark/matching.rb +0 -98
  27. data/benchmark/redactor.rb +0 -64
  28. data/benchmark/relay.rb +0 -48
  29. data/benchmark/scaling.rb +0 -70
  30. data/benchmark/send_slow.rb +0 -41
  31. data/benchmark/support.rb +0 -114
  32. data/docs/COMPATIBILITY.md +0 -98
  33. data/docs/INTERNAL_CONTRACTS.md +0 -154
  34. data/docs/PERFORMANCE.md +0 -165
  35. data/docs/RELEASING.md +0 -84
  36. data/docs/VERIFICATION.md +0 -456
  37. data/examples/dialogue.rb +0 -30
  38. data/examples/kibitz/README.md +0 -81
  39. data/examples/kibitz/kibitz.rb +0 -142
  40. data/examples/kibitz/test_kibitz.rb +0 -37
  41. data/examples/ssh_auto.rb +0 -94
  42. data/examples/ssh_interact.rb +0 -159
  43. data/examples/ssh_login.rb +0 -64
  44. data/expect-pty.gemspec +0 -33
  45. data/lib/expect/configuration.rb +0 -122
  46. data/lib/expect/terminal.rb +0 -102
  47. data/script/ci +0 -121
  48. data/script/release.rb +0 -319
  49. data/test/buffer_accounting_test.rb +0 -83
  50. data/test/cleanup_test.rb +0 -251
  51. data/test/compare_upstream.rb +0 -157
  52. data/test/configuration_test.rb +0 -133
  53. data/test/deadline_test.rb +0 -237
  54. data/test/diagnostics_test.rb +0 -353
  55. data/test/edge_case_test.rb +0 -262
  56. data/test/fixtures/ssh_scripts/01_identity.sh +0 -4
  57. data/test/fixtures/ssh_scripts/02_output.sh +0 -5
  58. data/test/fixtures/ssh_scripts/03_delayed.sh +0 -6
  59. data/test/fixtures/ssh_scripts/04_failure.sh +0 -2
  60. data/test/fixtures/ssh_scripts/05_recovery.sh +0 -3
  61. data/test/initialization_failure_test.rb +0 -92
  62. data/test/integration/README.md +0 -109
  63. data/test/integration/ssh_scripts.rb +0 -94
  64. data/test/interact_test.rb +0 -253
  65. data/test/interconnect_test.rb +0 -425
  66. data/test/io_test.rb +0 -321
  67. data/test/kibitz_test.rb +0 -45
  68. data/test/lifecycle_contract_test.rb +0 -71
  69. data/test/literal_scan_test.rb +0 -97
  70. data/test/matching_test.rb +0 -211
  71. data/test/multi_session_test.rb +0 -66
  72. data/test/ownership_sequence_test.rb +0 -208
  73. data/test/pattern_offset_test.rb +0 -43
  74. data/test/process_interruption_test.rb +0 -296
  75. data/test/process_test.rb +0 -291
  76. data/test/redactor_test.rb +0 -183
  77. data/test/relay_recovery_test.rb +0 -451
  78. data/test/relay_reentrancy_test.rb +0 -159
  79. data/test/release_test.rb +0 -375
  80. data/test/ruby_api_test.rb +0 -515
  81. data/test/scan_reuse_test.rb +0 -109
  82. data/test/script_logging_test.rb +0 -124
  83. data/test/support/interact_probe.rb +0 -125
  84. data/test/support/kibitz_probe.rb +0 -177
  85. data/test/support/script_probe.rb +0 -158
  86. data/test/terminal_cleanup_test.rb +0 -349
  87. data/test/test_helper.rb +0 -58
  88. data/test/timeout_test.rb +0 -289
  89. data/test/write_contract_test.rb +0 -105
data/sig/expect.rbs ADDED
@@ -0,0 +1,279 @@
1
+ # Public Session API; internal matching and relay protocols are documented with @api private.
2
+ module Expect
3
+ type duration = Numeric | String
4
+ type pattern = String | Regexp | :eof | :timeout
5
+ type result_error = :eof | :timeout | Exception | nil
6
+ type result_fields = { number: Integer?, error: result_error, match: String?, before: String?, after: String?, session: Session?, captures: Array[String?] }
7
+ type diagnostic_event = { event: Symbol, pid: Integer?, fd: Integer?, message: String }
8
+
9
+ interface _Writer
10
+ def write: (String) -> Integer
11
+ end
12
+
13
+ interface _Logger
14
+ def add: (Integer, diagnostic_event, String) -> untyped
15
+
16
+ def debug?: () -> bool
17
+ end
18
+
19
+ VERSION: String
20
+ CONTINUE: :continue
21
+ CONTINUE_WITHOUT_RESET: :continue_without_reset
22
+
23
+ class SpawnError < StandardError
24
+ end
25
+
26
+ class ReentrancyError < StandardError
27
+ end
28
+
29
+ class WriteTimeout < IOError
30
+ attr_reader bytes_written: Integer
31
+
32
+ def initialize: (?String message, ?bytes_written: Integer) -> void
33
+ end
34
+
35
+ def self.spawn: (
36
+ *String command, ?env: Hash[String, String?], ?chdir: String?, ?raw: bool, ?graceful: bool,
37
+ ?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
38
+ ?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
39
+ ) -> Session
40
+ | [A] (
41
+ *String command, ?env: Hash[String, String?], ?chdir: String?, ?raw: bool, ?graceful: bool,
42
+ ?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
43
+ ?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
44
+ ) { (Session) -> A } -> A
45
+
46
+ def self.open: (
47
+ IO io, ?writer: IO, ?own: bool, ?graceful: bool,
48
+ ?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
49
+ ?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
50
+ ) -> Session
51
+ | [A] (
52
+ IO io, ?writer: IO, ?own: bool, ?graceful: bool,
53
+ ?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
54
+ ?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
55
+ ) { (Session) -> A } -> A
56
+
57
+ def self.continue: (?reset_timeout: bool) -> (:continue | :continue_without_reset)
58
+
59
+ def self.monotonic: () -> Float
60
+
61
+ def self.duration: (duration?) -> Float?
62
+
63
+ def self.readable_sessions: (*Session sessions, ?timeout: duration?) -> Array[Session]
64
+
65
+ def self.interconnect: (*Session sessions, ?timeout: duration?) -> Session?
66
+
67
+ def self.expect: (
68
+ *pattern patterns, ?from: (Session | Array[Session]), ?timeout: duration?, ?deadline: duration?,
69
+ ?consume: bool, ?reset_timeout_on_read: bool
70
+ ) ?{ (PatternList) -> untyped } -> Result
71
+
72
+ class Session
73
+ def initialize: (
74
+ ?timeout: duration?, ?write_timeout: duration?, ?buffer_limit: Integer?,
75
+ ?logger: _Logger?, ?transcript: _Writer?, ?outputs: Array[_Writer]
76
+ ) -> void
77
+
78
+ def spawn: (*String command, ?env: Hash[String, String?], ?chdir: String?, ?raw: bool) -> Session
79
+
80
+ def expect: (
81
+ *pattern patterns, ?timeout: duration?, ?deadline: duration?, ?consume: bool, ?reset_timeout_on_read: bool
82
+ ) ?{ (PatternList) -> untyped } -> Result
83
+
84
+ def after: () -> String?
85
+
86
+ def before: () -> String?
87
+
88
+ def match: () -> String?
89
+
90
+ def alive?: () -> bool
91
+
92
+ def closed?: () -> bool
93
+
94
+ def eof?: () -> bool
95
+
96
+ def tty?: () -> bool
97
+
98
+ def pending_output?: () -> bool
99
+
100
+ def buffer: () -> String
101
+
102
+ def buffer=: (String value) -> void
103
+
104
+ def clear_buffer: () -> String
105
+
106
+ def buffer_discarded_bytes: () -> Integer
107
+
108
+ def captures: () -> Array[String?]
109
+
110
+ def command: () -> Array[String]?
111
+
112
+ def error: () -> result_error
113
+
114
+ def exit_code: () -> Integer?
115
+
116
+ def fileno: () -> Integer?
117
+
118
+ def pid: () -> Integer?
119
+
120
+ def match_number: () -> Integer?
121
+
122
+ def last_result: () -> Result?
123
+
124
+ def slave: () -> IO?
125
+
126
+ def tty_name: () -> String?
127
+
128
+ def to_io: () -> IO
129
+
130
+ def writer: () -> IO
131
+
132
+ def process_status: () -> Process::Status?
133
+
134
+ def inspect: () -> String
135
+
136
+ def close: (?graceful: bool) -> nil
137
+
138
+ def soft_close: (?timeout: duration?, ?term_timeout: duration) -> Process::Status?
139
+
140
+ def hard_close: (?timeout: duration) -> Process::Status?
141
+
142
+ def wait: (?timeout: duration?) -> Process::Status?
143
+
144
+ def write: (*untyped objects) -> Integer
145
+
146
+ def send_slow: (*untyped objects, delay: duration) -> Integer
147
+
148
+ def puts: (*untyped objects) -> nil
149
+
150
+ def <<: (untyped object) -> Session
151
+
152
+ def on_sequence: ((String | Regexp | :eof) sequence) ?{ () -> untyped } -> Session
153
+
154
+ def redact: (*String secrets) -> Session
155
+
156
+ def interact: (?input: (IO | Session), ?escape: (String | Regexp)?, ?output: _Writer?, ?timeout: duration?, ?raw: bool) -> Session?
157
+
158
+ def timeout: () -> Float?
159
+
160
+ def timeout=: (duration? value) -> void
161
+
162
+ def write_timeout: () -> Float?
163
+
164
+ def write_timeout=: (duration? value) -> void
165
+
166
+ def buffer_limit: () -> Integer?
167
+
168
+ def buffer_limit=: (Integer? value) -> void
169
+
170
+ def logger: () -> _Logger?
171
+
172
+ def logger=: (_Logger? value) -> void
173
+
174
+ def transcript: () -> _Writer?
175
+
176
+ def transcript=: (_Writer? value) -> void
177
+
178
+ def outputs: () -> Array[_Writer]
179
+
180
+ def outputs=: (Array[_Writer] value) -> void
181
+
182
+ def write_transcript: (*untyped objects) -> nil
183
+ end
184
+
185
+ class Result < Data
186
+ def self.new: (
187
+ ?number: Integer?,
188
+ ?error: result_error,
189
+ ?match: String?,
190
+ ?before: String?,
191
+ ?after: String?,
192
+ ?session: Session?,
193
+ ?captures: Array[String?]
194
+ ) -> Result
195
+ | (?Integer?, ?result_error, ?String?, ?String?, ?String?, ?Session?, ?Array[String?]) -> Result
196
+
197
+ def self.[]: (
198
+ ?number: Integer?,
199
+ ?error: result_error,
200
+ ?match: String?,
201
+ ?before: String?,
202
+ ?after: String?,
203
+ ?session: Session?,
204
+ ?captures: Array[String?]
205
+ ) -> Result
206
+ | (?Integer?, ?result_error, ?String?, ?String?, ?String?, ?Session?, ?Array[String?]) -> Result
207
+
208
+ def self.members: () -> Array[Symbol]
209
+
210
+ def self.inspect: () -> String
211
+
212
+ def members: () -> Array[Symbol]
213
+
214
+ attr_reader number: Integer?
215
+ attr_reader error: result_error
216
+ attr_reader match: String?
217
+ attr_reader before: String?
218
+ attr_reader after: String?
219
+ attr_reader session: Session?
220
+ attr_reader captures: Array[String?]
221
+
222
+ def initialize: (
223
+ ?number: Integer?,
224
+ ?error: result_error,
225
+ ?match: String?,
226
+ ?before: String?,
227
+ ?after: String?,
228
+ ?session: Session?,
229
+ ?captures: Array[String?]
230
+ ) -> void
231
+
232
+ def matched?: () -> bool
233
+
234
+ def timeout?: () -> bool
235
+
236
+ def eof?: () -> bool
237
+
238
+ def deconstruct: () -> [Integer?, result_error, String?, String?, String?, Session?, Array[String?]]
239
+
240
+ def with: (
241
+ ?number: Integer?,
242
+ ?error: result_error,
243
+ ?match: String?,
244
+ ?before: String?,
245
+ ?after: String?,
246
+ ?session: Session?,
247
+ ?captures: Array[String?]
248
+ ) -> Result
249
+
250
+ def to_h: () -> result_fields
251
+ | [K, V] () { (Symbol, untyped) -> [K, V] } -> Hash[K, V]
252
+
253
+ def deconstruct_keys: (Array[Symbol]?) -> Hash[Symbol, untyped]
254
+ end
255
+
256
+ class PatternList
257
+ def initialize: (?(Session | Array[Session]) sessions, ?Array[pattern] patterns) -> void
258
+
259
+ def on: ((String | Regexp) value, ?from: (Session | Array[Session])) ?{ (Session) -> untyped } -> PatternList
260
+
261
+ def eof: (?from: (Session | Array[Session])) ?{ (Session) -> untyped } -> PatternList
262
+
263
+ def timeout: () ?{ (Array[Session]) -> untyped } -> PatternList
264
+ end
265
+
266
+ class Redactor
267
+ def self.redact: (String data, Array[String] patterns, ?replacement: String) -> String
268
+
269
+ def initialize: (Array[String] patterns, ?replacement: String) -> void
270
+
271
+ def patterns=: (Array[String]) -> void
272
+
273
+ def append: (String) -> String
274
+
275
+ def finish: (?partial: bool) -> String
276
+
277
+ def inspect: () -> String
278
+ end
279
+ end
metadata CHANGED
@@ -1,28 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expect-pty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - expect-pty contributors
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-09-27 00:00:00.000000000 Z
10
+ date: 2026-10-01 00:00:00.000000000 Z
11
11
  dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: forwardable
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - "~>"
17
- - !ruby/object:Gem::Version
18
- version: '1.3'
19
- type: :runtime
20
- prerelease: false
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - "~>"
24
- - !ruby/object:Gem::Version
25
- version: '1.3'
26
12
  - !ruby/object:Gem::Dependency
27
13
  name: io-console
28
14
  requirement: !ruby/object:Gem::Requirement
@@ -30,9 +16,6 @@ dependencies:
30
16
  - - ">="
31
17
  - !ruby/object:Gem::Version
32
18
  version: '0.6'
33
- - - "<"
34
- - !ruby/object:Gem::Version
35
- version: '1.0'
36
19
  type: :runtime
37
20
  prerelease: false
38
21
  version_requirements: !ruby/object:Gem::Requirement
@@ -40,61 +23,32 @@ dependencies:
40
23
  - - ">="
41
24
  - !ruby/object:Gem::Version
42
25
  version: '0.6'
43
- - - "<"
44
- - !ruby/object:Gem::Version
45
- version: '1.0'
46
- - !ruby/object:Gem::Dependency
47
- name: io-wait
48
- requirement: !ruby/object:Gem::Requirement
49
- requirements:
50
- - - ">="
51
- - !ruby/object:Gem::Version
52
- version: '0.3'
53
- - - "<"
54
- - !ruby/object:Gem::Version
55
- version: '1.0'
56
- type: :runtime
57
- prerelease: false
58
- version_requirements: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: '0.3'
63
- - - "<"
64
- - !ruby/object:Gem::Version
65
- version: '1.0'
66
26
  - !ruby/object:Gem::Dependency
67
- name: shellwords
27
+ name: logger
68
28
  requirement: !ruby/object:Gem::Requirement
69
29
  requirements:
70
30
  - - ">="
71
31
  - !ruby/object:Gem::Version
72
- version: '0.1'
73
- - - "<"
74
- - !ruby/object:Gem::Version
75
- version: '1.0'
32
+ version: '1.6'
76
33
  type: :runtime
77
34
  prerelease: false
78
35
  version_requirements: !ruby/object:Gem::Requirement
79
36
  requirements:
80
37
  - - ">="
81
38
  - !ruby/object:Gem::Version
82
- version: '0.1'
83
- - - "<"
84
- - !ruby/object:Gem::Version
85
- version: '1.0'
39
+ version: '1.6'
86
40
  - !ruby/object:Gem::Dependency
87
41
  name: stringio
88
42
  requirement: !ruby/object:Gem::Requirement
89
43
  requirements:
90
- - - "~>"
44
+ - - ">="
91
45
  - !ruby/object:Gem::Version
92
46
  version: '3.0'
93
47
  type: :runtime
94
48
  prerelease: false
95
49
  version_requirements: !ruby/object:Gem::Requirement
96
50
  requirements:
97
- - - "~>"
51
+ - - ">="
98
52
  - !ruby/object:Gem::Version
99
53
  version: '3.0'
100
54
  description: Automate interactive programs with exact and regexp matching, Ruby blocks,
@@ -103,34 +57,13 @@ executables: []
103
57
  extensions: []
104
58
  extra_rdoc_files: []
105
59
  files:
106
- - ".rubocop.yml"
107
60
  - CHANGELOG.md
108
- - CONTRIBUTING.md
109
- - Gemfile
110
61
  - LICENSE
111
62
  - README.md
112
- - Rakefile
113
- - benchmark/matching.rb
114
- - benchmark/redactor.rb
115
- - benchmark/relay.rb
116
- - benchmark/scaling.rb
117
- - benchmark/send_slow.rb
118
- - benchmark/support.rb
119
- - docs/COMPATIBILITY.md
120
- - docs/INTERNAL_CONTRACTS.md
121
- - docs/PERFORMANCE.md
122
- - docs/RELEASING.md
123
- - docs/VERIFICATION.md
124
- - examples/dialogue.rb
125
- - examples/kibitz/README.md
126
- - examples/kibitz/kibitz.rb
127
- - examples/kibitz/test_kibitz.rb
128
- - examples/ssh_auto.rb
129
- - examples/ssh_interact.rb
130
- - examples/ssh_login.rb
131
- - expect-pty.gemspec
63
+ - docs/API.md
64
+ - docs/MIGRATION.md
132
65
  - lib/expect.rb
133
- - lib/expect/configuration.rb
66
+ - lib/expect/cleanup.rb
134
67
  - lib/expect/interaction.rb
135
68
  - lib/expect/logging.rb
136
69
  - lib/expect/matcher.rb
@@ -141,52 +74,10 @@ files:
141
74
  - lib/expect/relay.rb
142
75
  - lib/expect/relay_writer.rb
143
76
  - lib/expect/result.rb
77
+ - lib/expect/session.rb
144
78
  - lib/expect/session_resources.rb
145
- - lib/expect/terminal.rb
146
79
  - lib/expect/version.rb
147
- - script/ci
148
- - script/release.rb
149
- - test/buffer_accounting_test.rb
150
- - test/cleanup_test.rb
151
- - test/compare_upstream.rb
152
- - test/configuration_test.rb
153
- - test/deadline_test.rb
154
- - test/diagnostics_test.rb
155
- - test/edge_case_test.rb
156
- - test/fixtures/ssh_scripts/01_identity.sh
157
- - test/fixtures/ssh_scripts/02_output.sh
158
- - test/fixtures/ssh_scripts/03_delayed.sh
159
- - test/fixtures/ssh_scripts/04_failure.sh
160
- - test/fixtures/ssh_scripts/05_recovery.sh
161
- - test/initialization_failure_test.rb
162
- - test/integration/README.md
163
- - test/integration/ssh_scripts.rb
164
- - test/interact_test.rb
165
- - test/interconnect_test.rb
166
- - test/io_test.rb
167
- - test/kibitz_test.rb
168
- - test/lifecycle_contract_test.rb
169
- - test/literal_scan_test.rb
170
- - test/matching_test.rb
171
- - test/multi_session_test.rb
172
- - test/ownership_sequence_test.rb
173
- - test/pattern_offset_test.rb
174
- - test/process_interruption_test.rb
175
- - test/process_test.rb
176
- - test/redactor_test.rb
177
- - test/relay_recovery_test.rb
178
- - test/relay_reentrancy_test.rb
179
- - test/release_test.rb
180
- - test/ruby_api_test.rb
181
- - test/scan_reuse_test.rb
182
- - test/script_logging_test.rb
183
- - test/support/interact_probe.rb
184
- - test/support/kibitz_probe.rb
185
- - test/support/script_probe.rb
186
- - test/terminal_cleanup_test.rb
187
- - test/test_helper.rb
188
- - test/timeout_test.rb
189
- - test/write_contract_test.rb
80
+ - sig/expect.rbs
190
81
  homepage: https://github.com/gatework/expect-ruby
191
82
  licenses:
192
83
  - MIT
@@ -202,14 +93,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
202
93
  requirements:
203
94
  - - ">="
204
95
  - !ruby/object:Gem::Version
205
- version: '3.2'
96
+ version: '3.4'
206
97
  required_rubygems_version: !ruby/object:Gem::Requirement
207
98
  requirements:
208
99
  - - ">="
209
100
  - !ruby/object:Gem::Version
210
101
  version: '0'
211
102
  requirements: []
212
- rubygems_version: 4.0.12
103
+ rubygems_version: 4.0.16
213
104
  specification_version: 4
214
105
  summary: Ruby PTY automation with the Expect.pm interaction model
215
106
  test_files: []
data/.rubocop.yml DELETED
@@ -1,66 +0,0 @@
1
- AllCops:
2
- TargetRubyVersion: 3.2
3
- NewCops: enable
4
- SuggestExtensions: false
5
- Exclude:
6
- - "pkg/**/*"
7
- - "tmp/**/*"
8
- - "vendor/**/*"
9
-
10
- # 宽松但有限的规模门槛覆盖生产代码;测试和基准的场景编排不按方法长度及 ABC 计数。
11
- # 需要更高分支复杂度的协议状态机仅在对应方法说明豁免原因。
12
- Metrics/AbcSize:
13
- Max: 120
14
- Exclude:
15
- - "test/**/*"
16
- - "benchmark/**/*"
17
-
18
- Metrics/BlockLength:
19
- Max: 80
20
-
21
- Metrics/BlockNesting:
22
- Max: 4
23
- Exclude:
24
- - "test/**/*"
25
-
26
- Metrics/ClassLength:
27
- Max: 500
28
-
29
- Metrics/MethodLength:
30
- Max: 80
31
- Exclude:
32
- - "test/**/*"
33
- - "benchmark/**/*"
34
-
35
- Metrics/ModuleLength:
36
- Max: 250
37
-
38
- Metrics/ParameterLists:
39
- Max: 6
40
- CountKeywordArgs: false
41
-
42
- Metrics/CyclomaticComplexity:
43
- Max: 13
44
- Exclude:
45
- - "test/**/*"
46
-
47
- Metrics/PerceivedComplexity:
48
- Max: 13
49
- Exclude:
50
- - "test/**/*"
51
-
52
- Style/StringLiterals:
53
- EnforcedStyle: double_quotes
54
-
55
- Style/StringLiteralsInInterpolation:
56
- EnforcedStyle: double_quotes
57
-
58
- Style/Documentation:
59
- Exclude:
60
- - "test/**/*"
61
-
62
- Naming/RescuedExceptionsVariableName:
63
- PreferredName: error
64
-
65
- Layout/LineLength:
66
- Max: 120
data/CONTRIBUTING.md DELETED
@@ -1,29 +0,0 @@
1
- # 参与贡献
2
-
3
- 欢迎中文或英文 issue 和 PR。库的公共 API 名称和错误信息使用英文;库内的责任划分、复杂生命周期和协议解释使用中文,RuboCop
4
- 等工具指令保持原格式。文档以现有文件的语言为准,示例中的可编辑命令保持直接清晰。
5
-
6
- ## 本地检查
7
-
8
- 需要 Ruby 3.2+ 和 Linux/macOS。安装依赖后运行:
9
-
10
- ```sh
11
- bundle install
12
- bundle exec rake # RuboCop 和默认测试
13
- script/ci # 另含示例、Gem 构建及隔离安装验证
14
- ```
15
-
16
- 修改转接或匹配时,先运行对应的 `test/*_test.rb`,再运行 `bundle exec rake`。默认测试不需要 SSH;真实 SSH
17
- 集成测试的环境要求见 [测试说明](test/integration/README.md)。发布操作和历史验证分别见 [发布说明](docs/RELEASING.md)
18
- 与 [验证记录](docs/VERIFICATION.md)。
19
-
20
- RuboCop 对生产代码保留有限的长度、ABC、嵌套、参数数量和分支复杂度门槛。测试及基准的场景编排豁免方法长度与 ABC
21
- 计数;协议状态机的分支豁免只放在对应方法,并注明原因。阈值用于提示复核,职责拆分仍应保持状态归属和异常恢复逻辑完整。
22
-
23
- ## 提交问题或改动
24
-
25
- 问题报告请附 Ruby
26
- 版本、操作系统、最小复现代码、预期与实际结果,以及必要的异常信息;日志中请删去凭据和会话敏感内容。修复行为缺陷时,先加入能在旧实现复现问题的回归测试。涉及缓冲、转义、背压或进程清理的改动,请对照 [内部状态与数据归属](docs/INTERNAL_CONTRACTS.md)
27
- ,说明超时、EOF 和失败后的恢复行为。
28
-
29
- PR 请说明行为变化、运行过的命令及结果。不要把本机生成的 `tmp/`、日志或凭据加入提交。
data/Gemfile DELETED
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
- gemspec
5
-
6
- group :development, :test do
7
- gem "minitest", "~> 5.0", require: false
8
- # RuboCop 的依赖也必须支持最低 Ruby 版本。
9
- gem "parallel", "~> 1.27", require: false
10
- gem "rake", "~> 13.0", require: false
11
- # 固定已审阅的规则集,避免不同 CI 环境自动启用新 cop 改变发布门槛。
12
- gem "rubocop", "= 1.89.0", require: false
13
-
14
- # 测试、示例和发布工具直接使用的标准库 gem,不依赖其他开发工具间接引入。
15
- gem "digest", require: false
16
- gem "etc", require: false
17
- gem "fileutils", require: false
18
- gem "json", require: false
19
- gem "logger", require: false
20
- gem "net-http", require: false
21
- gem "open3", require: false
22
- gem "optparse", require: false
23
- gem "securerandom", require: false
24
- gem "tempfile", require: false
25
- gem "time", require: false
26
- gem "timeout", require: false
27
- gem "tmpdir", require: false
28
- end
data/Rakefile DELETED
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rake/testtask"
4
-
5
- Rake::TestTask.new do |task|
6
- task.libs << "test"
7
- task.pattern = "test/**/*_test.rb"
8
- task.warning = true
9
- end
10
-
11
- desc "Check Ruby style and common mistakes"
12
- task :lint do
13
- ruby "-S", "rubocop"
14
- end
15
-
16
- task default: %i[lint test]
17
-
18
- namespace :test do
19
- desc "Log in over SSH and verify multiple scripts and persisted logs (opt-in)"
20
- task :ssh do
21
- ruby "test/integration/ssh_scripts.rb"
22
- end
23
-
24
- desc "Log in over SSH and verify real PTY interact handoff (opt-in)"
25
- task :ssh_interact do
26
- ruby "examples/ssh_interact.rb", "--auto"
27
- end
28
-
29
- desc "Automatically log into local SSH and run read-only macOS checks"
30
- task :ssh_auto do
31
- ruby "examples/ssh_auto.rb", "--no-interact"
32
- end
33
-
34
- desc "Run the local two-terminal kibitz scenarios and save logs (no SSH required)"
35
- task :kibitz do
36
- ruby "examples/kibitz/test_kibitz.rb"
37
- end
38
- end