bashkit 0.1.16__tar.gz → 0.1.17__tar.gz

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 (407) hide show
  1. {bashkit-0.1.16 → bashkit-0.1.17}/Cargo.lock +6 -6
  2. {bashkit-0.1.16 → bashkit-0.1.17}/Cargo.toml +1 -1
  3. {bashkit-0.1.16 → bashkit-0.1.17}/PKG-INFO +1 -1
  4. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/archive.rs +17 -2
  5. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/date.rs +143 -6
  6. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/iconv.rs +119 -13
  7. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/posix.rs +88 -21
  8. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/interpreter/glob.rs +1 -1
  9. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/interpreter/mod.rs +264 -52
  10. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/lib.rs +152 -0
  11. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/snapshot_tests.rs +3 -3
  12. bashkit-0.1.17/crates/bashkit/tests/spec_cases/bash/append_redirect.test.sh +74 -0
  13. bashkit-0.1.17/crates/bashkit/tests/spec_cases/bash/command_v.test.sh +62 -0
  14. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/exec-fd-redirect.test.sh +9 -0
  15. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/pipes-redirects.test.sh +24 -0
  16. bashkit-0.1.17/crates/bashkit/tests/spec_cases/bash/tar_create.test.sh +29 -0
  17. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/threat_model_tests.rs +19 -1
  18. {bashkit-0.1.16 → bashkit-0.1.17}/README.md +0 -0
  19. {bashkit-0.1.16 → bashkit-0.1.17}/bashkit/__init__.py +0 -0
  20. {bashkit-0.1.16 → bashkit-0.1.17}/bashkit/_bashkit.pyi +0 -0
  21. {bashkit-0.1.16 → bashkit-0.1.17}/bashkit/deepagents.py +0 -0
  22. {bashkit-0.1.16 → bashkit-0.1.17}/bashkit/langchain.py +0 -0
  23. {bashkit-0.1.16 → bashkit-0.1.17}/bashkit/py.typed +0 -0
  24. {bashkit-0.1.16 → bashkit-0.1.17}/bashkit/pydantic_ai.py +0 -0
  25. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/Cargo.toml +0 -0
  26. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/README.md +0 -0
  27. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/benches/parallel_execution.rs +0 -0
  28. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/docs/compatibility.md +0 -0
  29. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/docs/custom_builtins.md +0 -0
  30. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/docs/live_mounts.md +0 -0
  31. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/docs/logging.md +0 -0
  32. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/docs/python.md +0 -0
  33. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/docs/ssh.md +0 -0
  34. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/docs/threat-model.md +0 -0
  35. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/docs/typescript.md +0 -0
  36. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/agent_tool.rs +0 -0
  37. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/basic.rs +0 -0
  38. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/custom_backend.rs +0 -0
  39. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/custom_builtins.rs +0 -0
  40. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/custom_filesystem_impl.rs +0 -0
  41. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/custom_fs.rs +0 -0
  42. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/git_workflow.rs +0 -0
  43. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/live_mounts.rs +0 -0
  44. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/python_external_functions.rs +0 -0
  45. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/python_scripts.rs +0 -0
  46. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/realfs_readonly.rs +0 -0
  47. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/realfs_readwrite.rs +0 -0
  48. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/resource_limits.rs +0 -0
  49. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/scripted_tool.rs +0 -0
  50. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/show_tool_output.rs +0 -0
  51. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/ssh_supabase.rs +0 -0
  52. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/streaming_output.rs +0 -0
  53. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/text_files.rs +0 -0
  54. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/text_processing.rs +0 -0
  55. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/typescript_external_functions.rs +0 -0
  56. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/typescript_scripts.rs +0 -0
  57. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/examples/virtual_identity.rs +0 -0
  58. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/alias.rs +0 -0
  59. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/arg_parser.rs +0 -0
  60. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/assert.rs +0 -0
  61. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/awk.rs +0 -0
  62. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/base64.rs +0 -0
  63. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/bc.rs +0 -0
  64. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/caller.rs +0 -0
  65. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/cat.rs +0 -0
  66. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/checksum.rs +0 -0
  67. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/clear.rs +0 -0
  68. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/column.rs +0 -0
  69. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/comm.rs +0 -0
  70. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/compgen.rs +0 -0
  71. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/csv.rs +0 -0
  72. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/curl.rs +0 -0
  73. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/cuttr.rs +0 -0
  74. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/diff.rs +0 -0
  75. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/dirstack.rs +0 -0
  76. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/disk.rs +0 -0
  77. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/dotenv.rs +0 -0
  78. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/echo.rs +0 -0
  79. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/environ.rs +0 -0
  80. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/envsubst.rs +0 -0
  81. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/expand.rs +0 -0
  82. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/export.rs +0 -0
  83. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/expr.rs +0 -0
  84. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/fc.rs +0 -0
  85. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/fileops.rs +0 -0
  86. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/flow.rs +0 -0
  87. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/fold.rs +0 -0
  88. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/git.rs +0 -0
  89. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/glob_cmd.rs +0 -0
  90. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/grep.rs +0 -0
  91. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/headtail.rs +0 -0
  92. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/help.rs +0 -0
  93. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/hextools.rs +0 -0
  94. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/http.rs +0 -0
  95. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/inspect.rs +0 -0
  96. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/introspect.rs +0 -0
  97. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/join.rs +0 -0
  98. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/jq.rs +0 -0
  99. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/json.rs +0 -0
  100. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/log.rs +0 -0
  101. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/ls.rs +0 -0
  102. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/mapfile.rs +0 -0
  103. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/mkfifo.rs +0 -0
  104. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/mod.rs +0 -0
  105. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/navigation.rs +0 -0
  106. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/nl.rs +0 -0
  107. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/numfmt.rs +0 -0
  108. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/parallel.rs +0 -0
  109. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/paste.rs +0 -0
  110. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/patch.rs +0 -0
  111. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/path.rs +0 -0
  112. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/pipeline.rs +0 -0
  113. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/printf.rs +0 -0
  114. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/python.rs +0 -0
  115. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/read.rs +0 -0
  116. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/retry.rs +0 -0
  117. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/rg.rs +0 -0
  118. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/search_common.rs +0 -0
  119. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/sed.rs +0 -0
  120. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/semver.rs +0 -0
  121. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/seq.rs +0 -0
  122. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/sleep.rs +0 -0
  123. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/sortuniq.rs +0 -0
  124. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/source.rs +0 -0
  125. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/split.rs +0 -0
  126. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/ssh.rs +0 -0
  127. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/strings.rs +0 -0
  128. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/system.rs +0 -0
  129. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/template.rs +0 -0
  130. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/test.rs +0 -0
  131. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/textrev.rs +0 -0
  132. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/timeout.rs +0 -0
  133. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/tomlq.rs +0 -0
  134. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/trap.rs +0 -0
  135. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/tree.rs +0 -0
  136. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/typescript.rs +0 -0
  137. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/vars.rs +0 -0
  138. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/verify.rs +0 -0
  139. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/wait.rs +0 -0
  140. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/wc.rs +0 -0
  141. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/yaml.rs +0 -0
  142. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/yes.rs +0 -0
  143. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/builtins/zip_cmd.rs +0 -0
  144. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/error.rs +0 -0
  145. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/backend.rs +0 -0
  146. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/limits.rs +0 -0
  147. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/memory.rs +0 -0
  148. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/mod.rs +0 -0
  149. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/mountable.rs +0 -0
  150. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/overlay.rs +0 -0
  151. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/realfs.rs +0 -0
  152. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/search.rs +0 -0
  153. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/fs/traits.rs +0 -0
  154. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/git/client.rs +0 -0
  155. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/git/config.rs +0 -0
  156. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/git/mod.rs +0 -0
  157. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/interpreter/jobs.rs +0 -0
  158. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/interpreter/state.rs +0 -0
  159. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/limits.rs +0 -0
  160. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/logging_impl.rs +0 -0
  161. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/network/allowlist.rs +0 -0
  162. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/network/bot_auth.rs +0 -0
  163. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/network/client.rs +0 -0
  164. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/network/mod.rs +0 -0
  165. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/parser/ast.rs +0 -0
  166. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/parser/budget.rs +0 -0
  167. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/parser/lexer.rs +0 -0
  168. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/parser/mod.rs +0 -0
  169. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/parser/span.rs +0 -0
  170. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/parser/tokens.rs +0 -0
  171. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/scripted_tool/execute.rs +0 -0
  172. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/scripted_tool/mod.rs +0 -0
  173. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/scripted_tool/toolset.rs +0 -0
  174. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/snapshot.rs +0 -0
  175. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/ssh/allowlist.rs +0 -0
  176. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/ssh/client.rs +0 -0
  177. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/ssh/config.rs +0 -0
  178. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/ssh/handler.rs +0 -0
  179. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/ssh/mod.rs +0 -0
  180. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/ssh/russh_handler.rs +0 -0
  181. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/tool.rs +0 -0
  182. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/src/trace.rs +0 -0
  183. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/allexport_tests.rs +0 -0
  184. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/awk_fuzz_scaffold_tests.rs +0 -0
  185. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/awk_newline_tests.rs +0 -0
  186. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/awk_pattern_tests.rs +0 -0
  187. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/awk_printf_expr_test.rs +0 -0
  188. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/background_exec_tests.rs +0 -0
  189. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/bash_source_tests.rs +0 -0
  190. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/blackbox_security_tests.rs +0 -0
  191. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/builtin_error_security_tests.rs +0 -0
  192. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/byte_range_panic_tests.rs +0 -0
  193. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/cancellation_tests.rs +0 -0
  194. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/cmdsub_quote_test.rs +0 -0
  195. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/coproc_tests.rs +0 -0
  196. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/custom_builtins_tests.rs +0 -0
  197. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/custom_fs_tests.rs +0 -0
  198. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/dev_null_tests.rs +0 -0
  199. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/final_env_tests.rs +0 -0
  200. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/find_multi_path_tests.rs +0 -0
  201. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/git_advanced_tests.rs +0 -0
  202. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/git_inspection_tests.rs +0 -0
  203. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/git_integration_tests.rs +0 -0
  204. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/git_remote_security_tests.rs +0 -0
  205. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/git_security_tests.rs +0 -0
  206. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/history_tests.rs +0 -0
  207. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_274_test.rs +0 -0
  208. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_275_279_282_test.rs +0 -0
  209. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_276_test.rs +0 -0
  210. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_277_test.rs +0 -0
  211. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_289_test.rs +0 -0
  212. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_290_test.rs +0 -0
  213. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_291_test.rs +0 -0
  214. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_853_test.rs +0 -0
  215. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_872_test.rs +0 -0
  216. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_873_test.rs +0 -0
  217. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/issue_875_test.rs +0 -0
  218. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/jq_fuzz_scaffold_tests.rs +0 -0
  219. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/live_mount_tests.rs +0 -0
  220. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/logging_security_tests.rs +0 -0
  221. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/mkfifo_tests.rs +0 -0
  222. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/nested_subscript_tests.rs +0 -0
  223. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/network_security_tests.rs +0 -0
  224. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/output_truncation_tests.rs +0 -0
  225. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/overlay_path_validation_tests.rs +0 -0
  226. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/proptest_differential.rs +0 -0
  227. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/proptest_security.rs +0 -0
  228. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/python_integration_tests.rs +0 -0
  229. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/python_security_tests.rs +0 -0
  230. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/realfs_tests.rs +0 -0
  231. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/regex_limit_tests.rs +0 -0
  232. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/script_execution_tests.rs +0 -0
  233. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/security_audit_pocs.rs +0 -0
  234. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/security_failpoint_tests.rs +0 -0
  235. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/set_e_and_or_tests.rs +0 -0
  236. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/azure_discover_rank.sh +0 -0
  237. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/azure_generate_url.sh +0 -0
  238. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/azure_query_capacity.sh +0 -0
  239. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/helm_validate_chart.sh +0 -0
  240. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/jwt_test_setup.sh +0 -0
  241. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/stitch_download_asset.sh +0 -0
  242. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/stitch_fetch.sh +0 -0
  243. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/stitch_verify_setup.sh +0 -0
  244. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/superpowers_find_polluter.sh +0 -0
  245. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_fixtures/vercel_deploy.sh +0 -0
  246. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/skills_tests.rs +0 -0
  247. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/source_function_tests.rs +0 -0
  248. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/awk/awk.test.sh +0 -0
  249. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/awk/delete-array.test.sh +0 -0
  250. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/awk/dev-stderr.test.sh +0 -0
  251. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/awk/eval-bugs.test.sh +0 -0
  252. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/awk/filename.test.sh +0 -0
  253. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/awk/getline-file.test.sh +0 -0
  254. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/alias.test.sh +0 -0
  255. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/arith-dynamic.test.sh +0 -0
  256. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/arithmetic-base-expansion.test.sh +0 -0
  257. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/arithmetic.test.sh +0 -0
  258. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/array-slicing.test.sh +0 -0
  259. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/array-splat.test.sh +0 -0
  260. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/arrays.test.sh +0 -0
  261. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/assoc-arrays.test.sh +0 -0
  262. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/awk-printf-width.test.sh +0 -0
  263. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/background.test.sh +0 -0
  264. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/bash-c-exports.test.sh +0 -0
  265. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/bash-command.test.sh +0 -0
  266. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/bash-flags.test.sh +0 -0
  267. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/bash-source-var.test.sh +0 -0
  268. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/bash-stdin-pipe.test.sh +0 -0
  269. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/bc.test.sh +0 -0
  270. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/blackbox-edge-cases.test.sh +0 -0
  271. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/blackbox-exploration.test.sh +0 -0
  272. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/brace-expansion.test.sh +0 -0
  273. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/brace_expansion_lookahead.test.sh +0 -0
  274. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/checksum.test.sh +0 -0
  275. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/chown-kill.test.sh +0 -0
  276. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/cmd-suggestions.test.sh +0 -0
  277. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/cmdsub_depth_unquoted.test.sh +0 -0
  278. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/column.test.sh +0 -0
  279. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/comm.test.sh +0 -0
  280. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/command-not-found.test.sh +0 -0
  281. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/command-subst.test.sh +0 -0
  282. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/command.test.sh +0 -0
  283. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/compgen-path.test.sh +0 -0
  284. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/conditional-short-circuit.test.sh +0 -0
  285. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/conditional.test.sh +0 -0
  286. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/control-flow.test.sh +0 -0
  287. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/cuttr.test.sh +0 -0
  288. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/date.test.sh +0 -0
  289. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/declare.test.sh +0 -0
  290. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/df.test.sh +0 -0
  291. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/diff.test.sh +0 -0
  292. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/dirstack.test.sh +0 -0
  293. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/du.test.sh +0 -0
  294. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/echo.test.sh +0 -0
  295. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/empty-bodies.test.sh +0 -0
  296. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/env.test.sh +0 -0
  297. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/errexit.test.sh +0 -0
  298. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/eval-bugs.test.sh +0 -0
  299. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/exec-command.test.sh +0 -0
  300. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/exec-fd-variable.test.sh +0 -0
  301. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/exit-status.test.sh +0 -0
  302. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/expr.test.sh +0 -0
  303. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/extglob.test.sh +0 -0
  304. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/file.test.sh +0 -0
  305. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/fileops.test.sh +0 -0
  306. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/find.test.sh +0 -0
  307. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/functions.test.sh +0 -0
  308. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/getopts.test.sh +0 -0
  309. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/glob-options.test.sh +0 -0
  310. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/glob_match_cap.test.sh +0 -0
  311. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/globs.test.sh +0 -0
  312. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/gzip.test.sh +0 -0
  313. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/headtail.test.sh +0 -0
  314. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/heredoc-edge.test.sh +0 -0
  315. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/heredoc.test.sh +0 -0
  316. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/herestring.test.sh +0 -0
  317. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/hextools.test.sh +0 -0
  318. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/history.test.sh +0 -0
  319. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/indirect-expansion.test.sh +0 -0
  320. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/less.test.sh +0 -0
  321. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/ln.test.sh +0 -0
  322. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/ls.test.sh +0 -0
  323. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/memory_budget_desync.test.sh +0 -0
  324. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/nameref-assoc.test.sh +0 -0
  325. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/nameref.test.sh +0 -0
  326. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/negative-tests.test.sh +0 -0
  327. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/nl.test.sh +0 -0
  328. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/nounset.test.sh +0 -0
  329. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/numfmt.test.sh +0 -0
  330. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/parse-errors.test.sh +0 -0
  331. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/paste-flags.test.sh +0 -0
  332. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/paste.test.sh +0 -0
  333. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/path.test.sh +0 -0
  334. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/printenv.test.sh +0 -0
  335. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/printf.test.sh +0 -0
  336. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/procsub.test.sh +0 -0
  337. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/quote.test.sh +0 -0
  338. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/read-builtin.test.sh +0 -0
  339. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/recursive-cmdsub.test.sh +0 -0
  340. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/regex-limit.test.sh +0 -0
  341. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/replace_pattern_limit.test.sh +0 -0
  342. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/script-exec.test.sh +0 -0
  343. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/seq.test.sh +0 -0
  344. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/set-allexport.test.sh +0 -0
  345. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/shell-grammar.test.sh +0 -0
  346. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/sleep.test.sh +0 -0
  347. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/sortuniq.test.sh +0 -0
  348. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/source.test.sh +0 -0
  349. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/stat.test.sh +0 -0
  350. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/string-ops.test.sh +0 -0
  351. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/strings.test.sh +0 -0
  352. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/subprocess-isolation.test.sh +0 -0
  353. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/subshell.test.sh +0 -0
  354. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/tar.test.sh +0 -0
  355. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/tee.test.sh +0 -0
  356. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/temp-binding.test.sh +0 -0
  357. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/test-operators.test.sh +0 -0
  358. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/test-tty.test.sh +0 -0
  359. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/textrev.test.sh +0 -0
  360. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/time.test.sh +0 -0
  361. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/timeout.test.sh +0 -0
  362. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/tree.test.sh +0 -0
  363. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/type.test.sh +0 -0
  364. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/unicode.test.sh +0 -0
  365. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/unset-exported-var.test.sh +0 -0
  366. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/var-op-test.test.sh +0 -0
  367. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/variables.test.sh +0 -0
  368. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/wait.test.sh +0 -0
  369. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/watch.test.sh +0 -0
  370. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/wc.test.sh +0 -0
  371. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/word-split.test.sh +0 -0
  372. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/bash/xargs.test.sh +0 -0
  373. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/grep/eval-bugs.test.sh +0 -0
  374. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/grep/grep.test.sh +0 -0
  375. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/grep/rg.test.sh +0 -0
  376. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/jq/jq.test.sh +0 -0
  377. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/python/env_leak.test.sh +0 -0
  378. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/python/python.test.sh +0 -0
  379. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/sed/eval-bugs.test.sh +0 -0
  380. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/sed/sed.test.sh +0 -0
  381. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_cases/typescript/typescript.test.sh +0 -0
  382. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_runner.rs +0 -0
  383. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/spec_tests.rs +0 -0
  384. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/ssh_builtin_tests.rs +0 -0
  385. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/ssh_supabase_tests.rs +0 -0
  386. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/stack_overflow_regression_tests.rs +0 -0
  387. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/subst_depth_limit_tests.rs +0 -0
  388. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/symlink_overlay_security_tests.rs +0 -0
  389. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/tty_tests.rs +0 -0
  390. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/typescript_integration_tests.rs +0 -0
  391. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/typescript_security_tests.rs +0 -0
  392. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/unicode_security_tests.rs +0 -0
  393. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/unset_function_tests.rs +0 -0
  394. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit/tests/urandom_tests.rs +0 -0
  395. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/Cargo.toml +0 -0
  396. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/README.md +0 -0
  397. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/examples/bash_basics.py +0 -0
  398. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/examples/k8s_orchestrator.py +0 -0
  399. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/src/lib.rs +0 -0
  400. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/tests/test_bashkit.py +0 -0
  401. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/tests/test_frameworks.py +0 -0
  402. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/tests/test_integration.py +0 -0
  403. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/tests/test_python_security.py +0 -0
  404. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/tests/test_security.py +0 -0
  405. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/tests/test_security_advanced.py +0 -0
  406. {bashkit-0.1.16 → bashkit-0.1.17}/crates/bashkit-python/tests/test_shell_injection.py +0 -0
  407. {bashkit-0.1.16 → bashkit-0.1.17}/pyproject.toml +0 -0
@@ -319,7 +319,7 @@ checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
319
319
 
320
320
  [[package]]
321
321
  name = "bashkit"
322
- version = "0.1.16"
322
+ version = "0.1.17"
323
323
  dependencies = [
324
324
  "anyhow",
325
325
  "async-trait",
@@ -362,7 +362,7 @@ dependencies = [
362
362
 
363
363
  [[package]]
364
364
  name = "bashkit-bench"
365
- version = "0.1.16"
365
+ version = "0.1.17"
366
366
  dependencies = [
367
367
  "anyhow",
368
368
  "bashkit",
@@ -378,7 +378,7 @@ dependencies = [
378
378
 
379
379
  [[package]]
380
380
  name = "bashkit-cli"
381
- version = "0.1.16"
381
+ version = "0.1.17"
382
382
  dependencies = [
383
383
  "anyhow",
384
384
  "bashkit",
@@ -391,7 +391,7 @@ dependencies = [
391
391
 
392
392
  [[package]]
393
393
  name = "bashkit-eval"
394
- version = "0.1.16"
394
+ version = "0.1.17"
395
395
  dependencies = [
396
396
  "anyhow",
397
397
  "async-trait",
@@ -407,7 +407,7 @@ dependencies = [
407
407
 
408
408
  [[package]]
409
409
  name = "bashkit-js"
410
- version = "0.1.16"
410
+ version = "0.1.17"
411
411
  dependencies = [
412
412
  "bashkit",
413
413
  "napi",
@@ -420,7 +420,7 @@ dependencies = [
420
420
 
421
421
  [[package]]
422
422
  name = "bashkit-python"
423
- version = "0.1.16"
423
+ version = "0.1.17"
424
424
  dependencies = [
425
425
  "bashkit",
426
426
  "num-bigint",
@@ -7,7 +7,7 @@ resolver = "2"
7
7
  members = ["crates/*"]
8
8
 
9
9
  [workspace.package]
10
- version = "0.1.16"
10
+ version = "0.1.17"
11
11
  edition = "2024"
12
12
  license = "MIT"
13
13
  authors = ["Everruns"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bashkit
3
- Version: 0.1.16
3
+ Version: 0.1.17
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -165,7 +165,15 @@ impl Builtin for Tar {
165
165
  2,
166
166
  ));
167
167
  }
168
- create_tar(&ctx, &archive_name, &files, verbose, gzip).await
168
+ create_tar(
169
+ &ctx,
170
+ &archive_name,
171
+ &files,
172
+ verbose,
173
+ gzip,
174
+ change_dir.as_deref(),
175
+ )
176
+ .await
169
177
  } else if extract {
170
178
  extract_tar(
171
179
  &ctx,
@@ -192,12 +200,19 @@ async fn create_tar(
192
200
  files: &[String],
193
201
  verbose: bool,
194
202
  gzip: bool,
203
+ change_dir: Option<&str>,
195
204
  ) -> Result<ExecResult> {
196
205
  let mut output_data: Vec<u8> = Vec::new();
197
206
  let mut verbose_output = String::new();
198
207
 
208
+ let base_dir = if let Some(dir) = change_dir {
209
+ resolve_path(ctx.cwd, dir)
210
+ } else {
211
+ ctx.cwd.clone()
212
+ };
213
+
199
214
  for file in files {
200
- let path = resolve_path(ctx.cwd, file);
215
+ let path = resolve_path(&base_dir, file);
201
216
 
202
217
  if !ctx.fs.exists(&path).await.unwrap_or(false) {
203
218
  return Ok(ExecResult::err(
@@ -6,6 +6,7 @@
6
6
  //! caught and return graceful errors.
7
7
 
8
8
  use std::fmt::Write;
9
+ use std::path::Path;
9
10
 
10
11
  use async_trait::async_trait;
11
12
  use chrono::format::{Item, StrftimeItems};
@@ -17,13 +18,14 @@ use crate::interpreter::ExecResult;
17
18
 
18
19
  /// The date builtin - display or set date and time.
19
20
  ///
20
- /// Usage: date [+FORMAT] [-u] [-R] [-I[TIMESPEC]]
21
+ /// Usage: date [+FORMAT] [-u] [-R] [-I[TIMESPEC]] [-r FILE]
21
22
  ///
22
23
  /// Options:
23
24
  /// +FORMAT Output date according to FORMAT
24
25
  /// -u Display UTC time instead of local time
25
26
  /// -R Output RFC 2822 formatted date
26
27
  /// -I[FMT] Output ISO 8601 formatted date (FMT: date, hours, minutes, seconds)
28
+ /// -r FILE Display the last modification time of FILE
27
29
  ///
28
30
  /// FORMAT specifiers:
29
31
  /// %Y Year with century (e.g., 2024)
@@ -327,6 +329,7 @@ impl Builtin for Date {
327
329
  let mut utc = false;
328
330
  let mut format_arg: Option<String> = None;
329
331
  let mut date_str: Option<String> = None;
332
+ let mut ref_file: Option<String> = None;
330
333
  let mut rfc2822 = false;
331
334
  let mut iso8601: Option<String> = None;
332
335
 
@@ -343,6 +346,15 @@ impl Builtin for Date {
343
346
  if let Some(val) = p.positional() {
344
347
  date_str = Some(val.to_string());
345
348
  }
349
+ } else if let Some(val) = p.current().and_then(|s| s.strip_prefix("--reference=")) {
350
+ ref_file = Some(val.to_string());
351
+ p.advance();
352
+ } else if let Some(val) = p.flag_value_opt("-r") {
353
+ ref_file = Some(val.to_string());
354
+ } else if p.flag("--reference") {
355
+ if let Some(val) = p.positional() {
356
+ ref_file = Some(val.to_string());
357
+ }
346
358
  } else if p.flag_any(&["-R", "--rfc-2822", "--rfc-email"]) {
347
359
  rfc2822 = true;
348
360
  } else if let Some(val) = p.current().and_then(|s| s.strip_prefix("--iso-8601=")) {
@@ -364,14 +376,34 @@ impl Builtin for Date {
364
376
  // Get the datetime to format
365
377
  // THREAT[TM-INF-018]: Use virtual time if configured
366
378
  let now = self.now();
367
- let epoch_input = date_str.as_deref().is_some_and(uses_epoch_input);
368
- let dt_utc = if let Some(ref ds) = date_str {
369
- match parse_date_string(ds, now) {
379
+
380
+ // Resolve the datetime: -r (file mtime) > -d (date string) > now
381
+ let epoch_input;
382
+ let dt_utc;
383
+ if let Some(ref file) = ref_file {
384
+ // -r / --reference: stat file to get modification time
385
+ let path = Path::new(file);
386
+ match ctx.fs.stat(path).await {
387
+ Ok(meta) => {
388
+ dt_utc = meta.modified.into();
389
+ epoch_input = false;
390
+ }
391
+ Err(_) => {
392
+ return Ok(ExecResult::err(
393
+ format!("date: cannot stat '{}': No such file or directory\n", file),
394
+ 1,
395
+ ));
396
+ }
397
+ }
398
+ } else if let Some(ref ds) = date_str {
399
+ epoch_input = uses_epoch_input(ds);
400
+ dt_utc = match parse_date_string(ds, now) {
370
401
  Ok(dt) => dt,
371
402
  Err(e) => return Ok(ExecResult::err(format!("{}\n", e), 1)),
372
- }
403
+ };
373
404
  } else {
374
- now
405
+ epoch_input = false;
406
+ dt_utc = now;
375
407
  };
376
408
 
377
409
  // Handle -R (RFC 2822) output
@@ -857,4 +889,109 @@ mod tests {
857
889
  // We only expand single %N, not %%N
858
890
  assert_eq!(expand_nanoseconds("%%N", 123), "%%N");
859
891
  }
892
+
893
+ // Helper to run date with a pre-configured filesystem
894
+ async fn run_date_with_fs(args: &[&str], fs: Arc<InMemoryFs>) -> ExecResult {
895
+ let mut variables = HashMap::new();
896
+ let env = HashMap::new();
897
+ let mut cwd = PathBuf::from("/");
898
+
899
+ let args: Vec<String> = args.iter().map(|s| s.to_string()).collect();
900
+ let ctx = Context {
901
+ args: &args,
902
+ env: &env,
903
+ variables: &mut variables,
904
+ cwd: &mut cwd,
905
+ fs,
906
+ stdin: None,
907
+ #[cfg(feature = "http_client")]
908
+ http_client: None,
909
+ #[cfg(feature = "git")]
910
+ git_client: None,
911
+ #[cfg(feature = "ssh")]
912
+ ssh_client: None,
913
+ shell: None,
914
+ };
915
+
916
+ Date::new().execute(ctx).await.unwrap()
917
+ }
918
+
919
+ // === -r / --reference (file mtime) tests ===
920
+
921
+ #[tokio::test]
922
+ async fn test_date_r_file_mtime() {
923
+ use crate::fs::FileSystem;
924
+
925
+ let fs = Arc::new(InMemoryFs::new());
926
+ fs.mkdir(std::path::Path::new("/tmp"), true).await.unwrap();
927
+ fs.write_file(std::path::Path::new("/tmp/test.txt"), b"hello")
928
+ .await
929
+ .unwrap();
930
+
931
+ // -r should return the file's mtime, not an error
932
+ let result = run_date_with_fs(&["-r", "/tmp/test.txt", "+%Y-%m-%d"], fs).await;
933
+ assert_eq!(result.exit_code, 0);
934
+ let date = result.stdout.trim();
935
+ // Should be a valid date (YYYY-MM-DD)
936
+ assert_eq!(date.len(), 10);
937
+ assert!(date.contains('-'));
938
+ }
939
+
940
+ #[tokio::test]
941
+ async fn test_date_r_file_not_found() {
942
+ let fs = Arc::new(InMemoryFs::new());
943
+ let result = run_date_with_fs(&["-r", "/nonexistent.txt"], fs).await;
944
+ assert_eq!(result.exit_code, 1);
945
+ assert!(result.stderr.contains("cannot stat"));
946
+ assert!(result.stderr.contains("/nonexistent.txt"));
947
+ }
948
+
949
+ #[tokio::test]
950
+ async fn test_date_r_with_format() {
951
+ use crate::fs::FileSystem;
952
+
953
+ let fs = Arc::new(InMemoryFs::new());
954
+ fs.mkdir(std::path::Path::new("/tmp"), true).await.unwrap();
955
+ fs.write_file(std::path::Path::new("/tmp/test.txt"), b"content")
956
+ .await
957
+ .unwrap();
958
+
959
+ let result = run_date_with_fs(&["-r", "/tmp/test.txt", "+%B"], fs).await;
960
+ assert_eq!(result.exit_code, 0);
961
+ // Should be a month name, non-empty
962
+ let month = result.stdout.trim();
963
+ assert!(!month.is_empty());
964
+ }
965
+
966
+ #[tokio::test]
967
+ async fn test_date_reference_long_flag() {
968
+ use crate::fs::FileSystem;
969
+
970
+ let fs = Arc::new(InMemoryFs::new());
971
+ fs.mkdir(std::path::Path::new("/tmp"), true).await.unwrap();
972
+ fs.write_file(std::path::Path::new("/tmp/test.txt"), b"content")
973
+ .await
974
+ .unwrap();
975
+
976
+ let result = run_date_with_fs(&["--reference=/tmp/test.txt", "+%Y"], fs).await;
977
+ assert_eq!(result.exit_code, 0);
978
+ let year = result.stdout.trim();
979
+ assert_eq!(year.len(), 4);
980
+ }
981
+
982
+ #[tokio::test]
983
+ async fn test_date_r_with_utc() {
984
+ use crate::fs::FileSystem;
985
+
986
+ let fs = Arc::new(InMemoryFs::new());
987
+ fs.mkdir(std::path::Path::new("/tmp"), true).await.unwrap();
988
+ fs.write_file(std::path::Path::new("/tmp/test.txt"), b"content")
989
+ .await
990
+ .unwrap();
991
+
992
+ let result = run_date_with_fs(&["-u", "-r", "/tmp/test.txt", "+%Z"], fs).await;
993
+ assert_eq!(result.exit_code, 0);
994
+ let tz = result.stdout.trim();
995
+ assert!(tz.contains("UTC") || tz == "+0000" || tz == "+00:00");
996
+ }
860
997
  }
@@ -17,6 +17,17 @@ use crate::interpreter::ExecResult;
17
17
  /// iconv builtin - character encoding conversion.
18
18
  pub struct Iconv;
19
19
 
20
+ /// Parse an encoding spec like "ascii//translit" into (encoding, translit).
21
+ fn parse_encoding_spec(spec: &str) -> (Option<&'static str>, bool) {
22
+ let (name, translit) = if let Some(pos) = spec.find("//") {
23
+ let suffix = &spec[pos + 2..];
24
+ (&spec[..pos], suffix.eq_ignore_ascii_case("translit"))
25
+ } else {
26
+ (spec, false)
27
+ };
28
+ (normalize_encoding(name), translit)
29
+ }
30
+
20
31
  /// Normalize encoding name to canonical form.
21
32
  fn normalize_encoding(name: &str) -> Option<&'static str> {
22
33
  match name.to_ascii_lowercase().replace('-', "").as_str() {
@@ -29,6 +40,54 @@ fn normalize_encoding(name: &str) -> Option<&'static str> {
29
40
  }
30
41
  }
31
42
 
43
+ /// Transliterate non-ASCII characters to their closest ASCII equivalents.
44
+ fn transliterate_to_ascii(input: &str) -> String {
45
+ let mut result = String::with_capacity(input.len());
46
+ for ch in input.chars() {
47
+ if ch.is_ascii() {
48
+ result.push(ch);
49
+ } else {
50
+ result.push(match ch {
51
+ 'á' | 'à' | 'â' | 'ã' | 'ä' | 'å' | 'ā' | 'ă' | 'ą' => 'a',
52
+ 'é' | 'è' | 'ê' | 'ë' | 'ē' | 'ĕ' | 'ė' | 'ę' | 'ě' => 'e',
53
+ 'í' | 'ì' | 'î' | 'ï' | 'ĩ' | 'ī' | 'ĭ' | 'į' => 'i',
54
+ 'ó' | 'ò' | 'ô' | 'õ' | 'ö' | 'ø' | 'ō' | 'ŏ' | 'ő' => 'o',
55
+ 'ú' | 'ù' | 'û' | 'ü' | 'ũ' | 'ū' | 'ŭ' | 'ů' | 'ű' | 'ų' => 'u',
56
+ 'ý' | 'ÿ' | 'ŷ' => 'y',
57
+ 'ñ' | 'ń' | 'ņ' | 'ň' => 'n',
58
+ 'ç' | 'ć' | 'č' | 'ĉ' | 'ċ' => 'c',
59
+ 'ß' => 's',
60
+ 'æ' => 'a',
61
+ 'œ' => 'o',
62
+ 'ð' => 'd',
63
+ 'þ' => 't',
64
+ 'ł' => 'l',
65
+ 'đ' => 'd',
66
+ 'ğ' => 'g',
67
+ 'ş' | 'š' | 'ś' | 'ŝ' => 's',
68
+ 'ž' | 'ź' | 'ż' => 'z',
69
+ 'ř' => 'r',
70
+ 'ť' | 'ţ' => 't',
71
+ 'Á' | 'À' | 'Â' | 'Ã' | 'Ä' | 'Å' => 'A',
72
+ 'É' | 'È' | 'Ê' | 'Ë' => 'E',
73
+ 'Í' | 'Ì' | 'Î' | 'Ï' => 'I',
74
+ 'Ó' | 'Ò' | 'Ô' | 'Õ' | 'Ö' | 'Ø' => 'O',
75
+ 'Ú' | 'Ù' | 'Û' | 'Ü' => 'U',
76
+ 'Ý' => 'Y',
77
+ 'Ñ' => 'N',
78
+ 'Ç' => 'C',
79
+ 'Š' => 'S',
80
+ 'Ž' => 'Z',
81
+ 'Ř' => 'R',
82
+ 'Ť' => 'T',
83
+ 'Ď' => 'D',
84
+ _ => '?',
85
+ });
86
+ }
87
+ }
88
+ result
89
+ }
90
+
32
91
  const SUPPORTED_ENCODINGS: &[&str] = &[
33
92
  "ASCII",
34
93
  "ISO-8859-1",
@@ -39,22 +98,33 @@ const SUPPORTED_ENCODINGS: &[&str] = &[
39
98
  ];
40
99
 
41
100
  /// Encode bytes from UTF-8 string into target encoding.
42
- fn encode_to(input: &str, encoding: &str) -> std::result::Result<Vec<u8>, String> {
101
+ /// When `transliterate` is true, non-ASCII characters are replaced with
102
+ /// ASCII equivalents before encoding (supports `//translit` mode).
103
+ fn encode_to(
104
+ input: &str,
105
+ encoding: &str,
106
+ transliterate: bool,
107
+ ) -> std::result::Result<Vec<u8>, String> {
108
+ let text = if transliterate {
109
+ transliterate_to_ascii(input)
110
+ } else {
111
+ input.to_string()
112
+ };
43
113
  match encoding {
44
- "utf-8" => Ok(input.as_bytes().to_vec()),
114
+ "utf-8" => Ok(text.as_bytes().to_vec()),
45
115
  "ascii" => {
46
- for (i, b) in input.bytes().enumerate() {
116
+ for (i, b) in text.bytes().enumerate() {
47
117
  if b > 127 {
48
118
  return Err(format!(
49
119
  "iconv: cannot convert character at byte {i} to ASCII\n"
50
120
  ));
51
121
  }
52
122
  }
53
- Ok(input.as_bytes().to_vec())
123
+ Ok(text.as_bytes().to_vec())
54
124
  }
55
125
  "latin1" => {
56
- let mut out = Vec::with_capacity(input.len());
57
- for ch in input.chars() {
126
+ let mut out = Vec::with_capacity(text.len());
127
+ for ch in text.chars() {
58
128
  let cp = ch as u32;
59
129
  if cp > 255 {
60
130
  return Err(format!("iconv: cannot convert U+{cp:04X} to LATIN1\n"));
@@ -67,7 +137,7 @@ fn encode_to(input: &str, encoding: &str) -> std::result::Result<Vec<u8>, String
67
137
  let mut out = Vec::new();
68
138
  // BOM little-endian
69
139
  out.extend_from_slice(&[0xFF, 0xFE]);
70
- for ch in input.chars() {
140
+ for ch in text.chars() {
71
141
  let mut buf = [0u16; 2];
72
142
  let encoded = ch.encode_utf16(&mut buf);
73
143
  for u in encoded {
@@ -78,7 +148,7 @@ fn encode_to(input: &str, encoding: &str) -> std::result::Result<Vec<u8>, String
78
148
  }
79
149
  "utf-16be" => {
80
150
  let mut out = Vec::new();
81
- for ch in input.chars() {
151
+ for ch in text.chars() {
82
152
  let mut buf = [0u16; 2];
83
153
  let encoded = ch.encode_utf16(&mut buf);
84
154
  for u in encoded {
@@ -227,10 +297,10 @@ impl Builtin for Iconv {
227
297
  }
228
298
  };
229
299
 
230
- let to = match &to_enc {
231
- Some(t) => match normalize_encoding(t) {
232
- Some(e) => e,
233
- None => {
300
+ let (to, to_translit) = match &to_enc {
301
+ Some(t) => match parse_encoding_spec(t) {
302
+ (Some(e), translit) => (e, translit),
303
+ (None, _) => {
234
304
  return Ok(ExecResult::err(
235
305
  format!("iconv: unsupported encoding '{}'\n", t),
236
306
  1,
@@ -268,7 +338,7 @@ impl Builtin for Iconv {
268
338
  };
269
339
 
270
340
  // Encode from UTF-8 string to target encoding
271
- let output_bytes = match encode_to(&text, to) {
341
+ let output_bytes = match encode_to(&text, to, to_translit) {
272
342
  Ok(b) => b,
273
343
  Err(e) => return Ok(ExecResult::err(e, 1)),
274
344
  };
@@ -415,4 +485,40 @@ mod tests {
415
485
  assert_eq!(r.exit_code, 0);
416
486
  assert_eq!(r.stdout, "hello world\n");
417
487
  }
488
+
489
+ #[tokio::test]
490
+ async fn test_translit_to_ascii() {
491
+ let r = run(
492
+ &["-f", "UTF-8", "-t", "ascii//translit"],
493
+ Some("caf\u{00e9}"),
494
+ None,
495
+ )
496
+ .await;
497
+ assert_eq!(r.exit_code, 0);
498
+ assert_eq!(r.stdout, "cafe");
499
+ }
500
+
501
+ #[tokio::test]
502
+ async fn test_translit_multiple_diacritics() {
503
+ let r = run(
504
+ &["-f", "UTF-8", "-t", "ASCII//TRANSLIT"],
505
+ Some("na\u{00ef}ve"),
506
+ None,
507
+ )
508
+ .await;
509
+ assert_eq!(r.exit_code, 0);
510
+ assert_eq!(r.stdout, "naive");
511
+ }
512
+
513
+ #[tokio::test]
514
+ async fn test_translit_german() {
515
+ let r = run(
516
+ &["-f", "utf-8", "-t", "ascii//translit"],
517
+ Some("H\u{00e9}llo W\u{00f6}rld"),
518
+ None,
519
+ )
520
+ .await;
521
+ assert_eq!(r.exit_code, 0);
522
+ assert_eq!(r.stdout, "Hello World");
523
+ }
418
524
  }