evolver-tools 30.0.0__tar.gz → 32.0.0__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 (303) hide show
  1. {evolver_tools-30.0.0/src/evolver_tools.egg-info → evolver_tools-32.0.0}/PKG-INFO +5 -5
  2. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/README.md +3 -3
  3. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/pyproject.toml +2 -2
  4. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/cli.py +1 -1
  5. evolver_tools-32.0.0/src/evolver_tools/vendor/csv_filter.py +120 -0
  6. evolver_tools-32.0.0/src/evolver_tools/vendor/csv_head.py +234 -0
  7. evolver_tools-32.0.0/src/evolver_tools/vendor/csv_sort.py +125 -0
  8. evolver_tools-32.0.0/src/evolver_tools/vendor/env_sorter.py +321 -0
  9. evolver_tools-32.0.0/src/evolver_tools/vendor/file_patch.py +189 -0
  10. evolver_tools-32.0.0/src/evolver_tools/vendor/file_type.py +297 -0
  11. evolver_tools-32.0.0/src/evolver_tools/vendor/find_empty.py +161 -0
  12. evolver_tools-32.0.0/src/evolver_tools/vendor/json_keys.py +160 -0
  13. evolver_tools-32.0.0/src/evolver_tools/vendor/link_check.py +219 -0
  14. evolver_tools-32.0.0/src/evolver_tools/vendor/mac_address.py +85 -0
  15. {evolver_tools-30.0.0 → evolver_tools-32.0.0/src/evolver_tools.egg-info}/PKG-INFO +5 -5
  16. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools.egg-info/SOURCES.txt +10 -0
  17. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/LICENSE +0 -0
  18. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/setup.cfg +0 -0
  19. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/__init__.py +0 -0
  20. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/__main__.py +0 -0
  21. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/autoreg.py +0 -0
  22. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/__init__.py +0 -0
  23. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/agent_b_tool.py +0 -0
  24. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ansi_strip.py +0 -0
  25. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/api_tester.py +0 -0
  26. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ascii_banner.py +0 -0
  27. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ascii_gen.py +0 -0
  28. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/audit_log.py +0 -0
  29. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/b64/__init__.py +0 -0
  30. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/b64/b64.py +0 -0
  31. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/backup.py +0 -0
  32. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/banner/__init__.py +0 -0
  33. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/banner/banner.py +0 -0
  34. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/base32.py +0 -0
  35. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/base58.py +0 -0
  36. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/bookmark.py +0 -0
  37. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/cal_tool/__init__.py +0 -0
  38. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/cal_tool/cli.py +0 -0
  39. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/calendar_cli.py +0 -0
  40. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/case_convert.py +0 -0
  41. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/cert_check.py +0 -0
  42. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/cert_info.py +0 -0
  43. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/changelog_gen/__init__.py +0 -0
  44. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/changelog_gen/changelog_gen.py +0 -0
  45. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/changelog_gen.py +0 -0
  46. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/chart_cli/__init__.py +0 -0
  47. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/chart_cli/__main__.py +0 -0
  48. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/checksum_dir.py +0 -0
  49. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/clipboard/__init__.py +0 -0
  50. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/clipboard/clipboard.py +0 -0
  51. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/code_auditor.py +0 -0
  52. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/code_review.py +0 -0
  53. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/code_stats.py +0 -0
  54. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/colorize.py +0 -0
  55. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/colors/__init__.py +0 -0
  56. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/colors/__main__.py +0 -0
  57. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/config_validator.py +0 -0
  58. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/config_vault.py +0 -0
  59. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/cowsay.py +0 -0
  60. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/crc_check.py +0 -0
  61. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/cron/__init__.py +0 -0
  62. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/cron/__main__.py +0 -0
  63. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/cron_pretty.py +0 -0
  64. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/crontab_helper.py +0 -0
  65. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/crypto_box.py +0 -0
  66. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/crypto_price.py +0 -0
  67. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv2json.py +0 -0
  68. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_dedup.py +0 -0
  69. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_merge.py +0 -0
  70. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_slice.py +0 -0
  71. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_stats/__init__.py +0 -0
  72. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_stats/__main__.py +0 -0
  73. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_stats/analyzer.py +0 -0
  74. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_stats/cli.py +0 -0
  75. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_to_table.py +0 -0
  76. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_validate.py +0 -0
  77. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/csv_view.py +0 -0
  78. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/date_diff.py +0 -0
  79. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/db_mate.py +0 -0
  80. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/db_schema.py +0 -0
  81. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/dedup_files.py +0 -0
  82. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/dep_graph.py +0 -0
  83. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/dev_dashboard.py +0 -0
  84. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/dice_roll.py +0 -0
  85. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/diff_csv.py +0 -0
  86. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/diff_files.py +0 -0
  87. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/diff_tool/__init__.py +0 -0
  88. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/diff_tool/__main__.py +0 -0
  89. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/dirsize/__init__.py +0 -0
  90. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/disk_cleanup.py +0 -0
  91. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/disk_usage/__init__.py +0 -0
  92. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/disk_usage/disk_usage.py +0 -0
  93. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/dns_lookup.py +0 -0
  94. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/docker_helper.py +0 -0
  95. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/dt_convert.py +0 -0
  96. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/env_diff.py +0 -0
  97. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/env_manager.py +0 -0
  98. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/env_template.py +0 -0
  99. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/envcheck/__init__.py +0 -0
  100. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/epoch.py +0 -0
  101. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/excel2csv.py +0 -0
  102. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/factor.py +0 -0
  103. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ff/__init__.py +0 -0
  104. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ff/__main__.py +0 -0
  105. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/figlet_cli.py +0 -0
  106. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/figlet_tool.py +0 -0
  107. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/file_encrypt.py +0 -0
  108. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/file_find.py +0 -0
  109. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/file_joiner.py +0 -0
  110. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/file_splitter.py +0 -0
  111. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/file_watch.py +0 -0
  112. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/find_dups/__init__.py +0 -0
  113. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/find_dups/cli.py +0 -0
  114. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/firewall_rule.py +0 -0
  115. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/fmt/__init__.py +0 -0
  116. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/fmt/fmt.py +0 -0
  117. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/fold.py +0 -0
  118. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/geo_ip.py +0 -0
  119. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/git_branch_cleaner.py +0 -0
  120. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/git_log_pretty.py +0 -0
  121. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/git_stats.py +0 -0
  122. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/gzip_cli.py +0 -0
  123. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/hash_check.py +0 -0
  124. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/hash_file.py +0 -0
  125. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/hashsum/__init__.py +0 -0
  126. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/hashsum/__main__.py +0 -0
  127. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/hex_tool.py +0 -0
  128. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/hexdump.py +0 -0
  129. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/html2markdown.py +0 -0
  130. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/html2md.py +0 -0
  131. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/http_headers.py +0 -0
  132. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/http_live/__init__.py +0 -0
  133. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/http_live/__main__.py +0 -0
  134. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/http_server.py +0 -0
  135. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/http_status.py +0 -0
  136. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/image_meta.py +0 -0
  137. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ini2json.py +0 -0
  138. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ini_parser/__init__.py +0 -0
  139. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ini_parser/ini_parser.py +0 -0
  140. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ip_info.py +0 -0
  141. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ip_location.py +0 -0
  142. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ipcalc/__init__.py +0 -0
  143. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ipcalc/__main__.py +0 -0
  144. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ipinfo/__init__.py +0 -0
  145. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ipinfo/__main__.py +0 -0
  146. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/join.py +0 -0
  147. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/joke.py +0 -0
  148. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/jq_lite/__init__.py +0 -0
  149. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/jq_lite/__main__.py +0 -0
  150. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json2csv/__init__.py +0 -0
  151. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json2csv/__main__.py +0 -0
  152. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json2ini.py +0 -0
  153. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_diff.py +0 -0
  154. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_flatten.py +0 -0
  155. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_merge.py +0 -0
  156. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_path.py +0 -0
  157. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_pretty/__init__.py +0 -0
  158. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_pretty/json_pretty.py +0 -0
  159. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_schema_validate.py +0 -0
  160. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_sort.py +0 -0
  161. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_to_table.py +0 -0
  162. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/json_to_yaml.py +0 -0
  163. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/jsonql/__init__.py +0 -0
  164. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/jsonql/__main__.py +0 -0
  165. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/jwt_decode.py +0 -0
  166. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/key_value_store.py +0 -0
  167. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/license.py +0 -0
  168. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/license_cli/__init__.py +0 -0
  169. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/license_cli/__main__.py +0 -0
  170. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/license_cli/cli.py +0 -0
  171. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/log_analyzer.py +0 -0
  172. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/log_hawk.py +0 -0
  173. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/log_tail.py +0 -0
  174. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/macrogen.py +0 -0
  175. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/markdown_check/__init__.py +0 -0
  176. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/markdown_lint.py +0 -0
  177. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/markdown_preview.py +0 -0
  178. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/markdown_to_html.py +0 -0
  179. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/markdown_toc.py +0 -0
  180. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/math_eval.py +0 -0
  181. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/media_studio.py +0 -0
  182. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/morse.py +0 -0
  183. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/nb/__init__.py +0 -0
  184. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/nb/__main__.py +0 -0
  185. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/net_analyzer.py +0 -0
  186. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/net_speed.py +0 -0
  187. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/network_scan.py +0 -0
  188. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/nl.py +0 -0
  189. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/note_taker.py +0 -0
  190. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/otp_gen.py +0 -0
  191. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/passgen/__init__.py +0 -0
  192. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/password_strength.py +0 -0
  193. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/pdf_info.py +0 -0
  194. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/pdf_text.py +0 -0
  195. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/pipe_viewer.py +0 -0
  196. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/pomodoro.py +0 -0
  197. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/port_scan.py +0 -0
  198. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/portcheck/__init__.py +0 -0
  199. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/portcheck/__main__.py +0 -0
  200. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/pr_tool/__init__.py +0 -0
  201. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/pr_tool/pr_tool.py +0 -0
  202. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/process_kill.py +0 -0
  203. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/progress_bar.py +0 -0
  204. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/project_doctor/__init__.py +0 -0
  205. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/project_doctor/__main__.py +0 -0
  206. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/qc_calc.py +0 -0
  207. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/qc_report.py +0 -0
  208. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/qc_sample.py +0 -0
  209. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/qr_cli.py +0 -0
  210. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/qrcode.py +0 -0
  211. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/quote.py +0 -0
  212. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/quote_tool/__init__.py +0 -0
  213. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/quote_tool/quote.py +0 -0
  214. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/rainbow.py +0 -0
  215. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/random.py +0 -0
  216. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/random_cli.py +0 -0
  217. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/random_string.py +0 -0
  218. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/reminder.py +0 -0
  219. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ren/__init__.py +0 -0
  220. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ren/__main__.py +0 -0
  221. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/replace_text.py +0 -0
  222. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/restore.py +0 -0
  223. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/rot13.py +0 -0
  224. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/route_trace.py +0 -0
  225. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/scan_open_ports.py +0 -0
  226. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/scan_ports.py +0 -0
  227. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/screen_recorder.py +0 -0
  228. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/screenshot_cli.py +0 -0
  229. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/search_files.py +0 -0
  230. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/search_history.py +0 -0
  231. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/secret_scanner.py +0 -0
  232. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/seq.py +0 -0
  233. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/service_check.py +0 -0
  234. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/shuffle.py +0 -0
  235. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/siege_lite/__init__.py +0 -0
  236. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/siege_lite/__main__.py +0 -0
  237. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/slugify.py +0 -0
  238. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/smellfinder/__init__.py +0 -0
  239. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/smellfinder/__main__.py +0 -0
  240. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/sort/__init__.py +0 -0
  241. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/sort/sort.py +0 -0
  242. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/spinner.py +0 -0
  243. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/split.py +0 -0
  244. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/split_tool/__init__.py +0 -0
  245. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/split_tool/split.py +0 -0
  246. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/sql2csv.py +0 -0
  247. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/sqlite_cli/__init__.py +0 -0
  248. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/sqlite_cli/__main__.py +0 -0
  249. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ssh_key_gen.py +0 -0
  250. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/ssl_check.py +0 -0
  251. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/stopwatch.py +0 -0
  252. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/subnet.py +0 -0
  253. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/sysmon/__init__.py +0 -0
  254. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/sysmon/__main__.py +0 -0
  255. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/sysmon_pro.py +0 -0
  256. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/system_info.py +0 -0
  257. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/temp_cleaner.py +0 -0
  258. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/template.py +0 -0
  259. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/text_dedent.py +0 -0
  260. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/text_stats.py +0 -0
  261. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/text_wrap.py +0 -0
  262. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/time_duration.py +0 -0
  263. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/timeout.py +0 -0
  264. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/timer/__init__.py +0 -0
  265. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/timer_pro/__init__.py +0 -0
  266. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/timer_pro/timer_pro.py +0 -0
  267. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/timer_pro.py +0 -0
  268. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/todo_cli.py +0 -0
  269. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/toml2json.py +0 -0
  270. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/tr.py +0 -0
  271. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/tree.py +0 -0
  272. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/treedir/__init__.py +0 -0
  273. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/treedir/__main__.py +0 -0
  274. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/tsv2csv.py +0 -0
  275. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/uniq_tool/__init__.py +0 -0
  276. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/uniq_tool/uniq.py +0 -0
  277. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/unit_convert.py +0 -0
  278. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/uri_encode.py +0 -0
  279. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/url_parser.py +0 -0
  280. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/urlparse_tool/__init__.py +0 -0
  281. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/urlparse_tool/cli.py +0 -0
  282. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/uuid_gen.py +0 -0
  283. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/uuid_tool/__init__.py +0 -0
  284. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/uuid_tool/__main__.py +0 -0
  285. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/watch.py +0 -0
  286. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/weather_cli.py +0 -0
  287. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/web_download.py +0 -0
  288. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/web_summary/__init__.py +0 -0
  289. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/web_summary/__main__.py +0 -0
  290. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/whois_lookup.py +0 -0
  291. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/wordcount/__init__.py +0 -0
  292. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/wordcount/__main__.py +0 -0
  293. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/world_clock.py +0 -0
  294. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/xml2json.py +0 -0
  295. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/xml_format.py +0 -0
  296. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/yaml2json/__init__.py +0 -0
  297. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/yaml2json/yaml2json.py +0 -0
  298. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/yaml2toml.py +0 -0
  299. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/yaml_validate.py +0 -0
  300. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools/vendor/yes.py +0 -0
  301. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools.egg-info/dependency_links.txt +0 -0
  302. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools.egg-info/entry_points.txt +0 -0
  303. {evolver_tools-30.0.0 → evolver_tools-32.0.0}/src/evolver_tools.egg-info/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evolver-tools
3
- Version: 30.0.0
4
- Summary: 233 CLI tools + 9 flagship projects — one pip install
3
+ Version: 32.0.0
4
+ Summary: 234 CLI tools + 9 flagship projects — one pip install
5
5
  Author: EVOLVER
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://evolver-dev.github.io/evolver-tools
@@ -22,11 +22,11 @@ Dynamic: license-file
22
22
 
23
23
  # EVOLVER Tools
24
24
 
25
- **233+ CLI tools + 9 flagship projects — one `pip install`.**
25
+ **238 CLI tools + 9 flagship projects — one `pip install`.**
26
26
 
27
- Zero-dependency (230/233), cross-platform, production-ready. Version **30.0.0**.
27
+ Zero-dependency (235/238), cross-platform, production-ready. Version **31.0.0**.
28
28
  Systems ops, data processing, text manipulation, security, dev tooling, and creative utilities.
29
- All in a single install — not 233 separate packages.
29
+ All in a single install — not 238 separate packages.
30
30
 
31
31
  ## Quick Start
32
32
 
@@ -1,10 +1,10 @@
1
1
  # EVOLVER Tools
2
2
 
3
- **233+ CLI tools + 9 flagship projects — one `pip install`.**
3
+ **238 CLI tools + 9 flagship projects — one `pip install`.**
4
4
 
5
- Zero-dependency (230/233), cross-platform, production-ready. Version **30.0.0**.
5
+ Zero-dependency (235/238), cross-platform, production-ready. Version **31.0.0**.
6
6
  Systems ops, data processing, text manipulation, security, dev tooling, and creative utilities.
7
- All in a single install — not 233 separate packages.
7
+ All in a single install — not 238 separate packages.
8
8
 
9
9
  ## Quick Start
10
10
 
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "evolver-tools"
7
- version = "30.0.0"
8
- description = "233 CLI tools + 9 flagship projects — one pip install"
7
+ version = "32.0.0"
8
+ description = "234 CLI tools + 9 flagship projects — one pip install"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  requires-python = ">=3.8"
@@ -14,7 +14,7 @@ from evolver_tools.autoreg import auto_discover
14
14
  def list_tools():
15
15
  """Display all available tools."""
16
16
  tools = auto_discover()
17
- print(f'\x1b[1;36m===== EVOLVER Tools v30.0.0 =====\x1b[0m')
17
+ print(f'\x1b[1;36m===== EVOLVER Tools v31.0.0 =====\x1b[0m')
18
18
  print()
19
19
  for name, info in sorted(tools.items()):
20
20
  print(f' \033[1;33m{name:<18}\033[0m {info["desc"]}')
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env python3
2
+ """csv_filter.py — Filter CSV rows by column value matching.
3
+
4
+ Usage:
5
+ cat data.csv | python csv_filter.py --column name --value Alice
6
+ python csv_filter.py data.csv --column age --value 30
7
+ python csv_filter.py data.csv --column city --value "New York" --delimiter ';'
8
+ python csv_filter.py data.csv --column status --value active --invert
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import csv
14
+ import sys
15
+ import argparse
16
+ from typing import Dict, List, Sequence, TextIO
17
+
18
+
19
+ TOOL_META = {
20
+ "name": "csv-filter",
21
+ "func": "main",
22
+ "desc": "Filter CSV rows by column value",
23
+ }
24
+
25
+
26
+ def build_parser() -> argparse.ArgumentParser:
27
+ parser = argparse.ArgumentParser(
28
+ description="Filter CSV rows by column value matching.",
29
+ )
30
+ parser.add_argument(
31
+ "file",
32
+ nargs="?",
33
+ default=None,
34
+ help="CSV file path (omit or use '-' to read from stdin)",
35
+ )
36
+ parser.add_argument(
37
+ "--column",
38
+ required=True,
39
+ help="Column name to filter on",
40
+ )
41
+ parser.add_argument(
42
+ "--value",
43
+ required=True,
44
+ help="Value to match (exact string match)",
45
+ )
46
+ parser.add_argument(
47
+ "--delimiter",
48
+ default=",",
49
+ help="CSV delimiter character (default: ',')",
50
+ )
51
+ parser.add_argument(
52
+ "--invert",
53
+ action="store_true",
54
+ default=False,
55
+ help="Invert match — print rows where column does NOT equal value",
56
+ )
57
+ return parser
58
+
59
+
60
+ def open_input(file_arg: str | None) -> TextIO:
61
+ """Return a file handle for the given argument or stdin."""
62
+ if file_arg is None or file_arg == "-":
63
+ return sys.stdin
64
+ return open(file_arg, newline="")
65
+
66
+
67
+ def filter_rows(
68
+ reader: csv.DictReader,
69
+ column: str,
70
+ value: str,
71
+ invert: bool,
72
+ ) -> List[Dict[str, str]]:
73
+ """Filter rows from a DictReader where column matches (or doesn't match) value."""
74
+ results: List[Dict[str, str]] = []
75
+ for row in reader:
76
+ cell = row.get(column, "")
77
+ if invert:
78
+ if cell != value:
79
+ results.append(row)
80
+ else:
81
+ if cell == value:
82
+ results.append(row)
83
+ return results
84
+
85
+
86
+ def write_rows(rows: List[Dict[str, str]], fieldnames: Sequence[str], delimiter: str) -> None:
87
+ """Write filtered rows to stdout as CSV."""
88
+ writer = csv.DictWriter(sys.stdout, fieldnames=fieldnames, delimiter=delimiter)
89
+ writer.writeheader()
90
+ writer.writerows(rows)
91
+
92
+
93
+ def main(argv: list[str] | None = None) -> None:
94
+ parser = build_parser()
95
+ args = parser.parse_args(argv)
96
+
97
+ fh = open_input(args.file)
98
+ try:
99
+ reader = csv.DictReader(fh, delimiter=args.delimiter)
100
+ if not reader.fieldnames:
101
+ sys.exit("error: CSV has no header row (column names required)")
102
+
103
+ fieldnames = reader.fieldnames
104
+
105
+ if args.column not in fieldnames:
106
+ sys.exit(
107
+ f"error: column '{args.column}' not found in CSV header. "
108
+ f"Available columns: {', '.join(fieldnames)}"
109
+ )
110
+
111
+ rows = filter_rows(reader, args.column, args.value, args.invert)
112
+ finally:
113
+ if fh is not sys.stdin:
114
+ fh.close()
115
+
116
+ write_rows(rows, fieldnames, args.delimiter)
117
+
118
+
119
+ if __name__ == "__main__":
120
+ main()
@@ -0,0 +1,234 @@
1
+ #!/usr/bin/env python3
2
+ """csv-head — Display first N rows of a CSV file.
3
+
4
+ Usage: csv-head data.csv
5
+ csv-head data.csv -n 20
6
+ csv-head data.csv --columns name,email
7
+ csv-head data.csv --format table
8
+ cat data.csv | csv-head -n 5
9
+
10
+ Options:
11
+ -n, --lines N Number of rows to show (default: 10)
12
+ -c, --columns NAMES Comma-separated column names to show
13
+ -f, --format FMT Output format: csv (default) or table
14
+ --no-header Input has no header row
15
+ -h, --help Show this help message
16
+ """
17
+
18
+ import csv
19
+ import io
20
+ import os
21
+ import sys
22
+
23
+ TOOL_META = {
24
+ "name": "csv-head",
25
+ "func": "main",
26
+ "desc": "Display first N rows of a CSV file",
27
+ }
28
+
29
+
30
+ def read_input(filepath=None):
31
+ """Read CSV data from file or stdin. Returns (content, source_name)."""
32
+ if filepath:
33
+ if not os.path.isfile(filepath):
34
+ print(f"Error: file not found: {filepath}", file=sys.stderr)
35
+ sys.exit(1)
36
+ try:
37
+ with open(filepath, "r", encoding="utf-8", errors="replace") as f:
38
+ content = f.read()
39
+ except Exception as e:
40
+ print(f"Error reading file: {e}", file=sys.stderr)
41
+ sys.exit(1)
42
+ return content, filepath
43
+ else:
44
+ try:
45
+ content = sys.stdin.read()
46
+ except KeyboardInterrupt:
47
+ sys.exit(1)
48
+ if not content.strip():
49
+ print("(no input)", file=sys.stderr)
50
+ sys.exit(1)
51
+ return content, "<stdin>"
52
+
53
+
54
+ def parse_csv(content):
55
+ """Parse CSV content into list of rows using csv.reader."""
56
+ reader = csv.reader(io.StringIO(content))
57
+ return [row for row in reader]
58
+
59
+
60
+ def filter_columns(rows, column_names, has_header):
61
+ """Filter rows to only include specified columns.
62
+
63
+ column_names is a list of column names (if has_header) or column indices.
64
+ """
65
+ if not rows or not column_names:
66
+ return rows
67
+
68
+ if has_header:
69
+ header = rows[0]
70
+ indices = []
71
+ for name in column_names:
72
+ name = name.strip()
73
+ found = False
74
+ for i, h in enumerate(header):
75
+ if h.strip() == name:
76
+ indices.append(i)
77
+ found = True
78
+ break
79
+ if not found:
80
+ print(f"Error: column '{name}' not found in header", file=sys.stderr)
81
+ sys.exit(1)
82
+ else:
83
+ # No header — column_names are 1-based indices
84
+ indices = []
85
+ for name in column_names:
86
+ name = name.strip()
87
+ try:
88
+ idx = int(name) - 1
89
+ if idx < 0:
90
+ print(f"Error: column index must be >= 1, got {name}", file=sys.stderr)
91
+ sys.exit(1)
92
+ indices.append(idx)
93
+ except ValueError:
94
+ print(f"Error: without --no-header, column names must be integers, got '{name}'", file=sys.stderr)
95
+ sys.exit(1)
96
+
97
+ filtered = []
98
+ for row in rows:
99
+ new_row = [row[i] if i < len(row) else "" for i in indices]
100
+ filtered.append(new_row)
101
+
102
+ return filtered
103
+
104
+
105
+ def format_csv(rows):
106
+ """Output rows as CSV."""
107
+ writer = csv.writer(sys.stdout)
108
+ for row in rows:
109
+ writer.writerow(row)
110
+
111
+
112
+ def format_table(rows):
113
+ """Output rows as an aligned table."""
114
+ if not rows:
115
+ return
116
+
117
+ num_cols = max(len(row) for row in rows) if rows else 0
118
+ if num_cols == 0:
119
+ return
120
+
121
+ col_widths = [0] * num_cols
122
+ for row in rows:
123
+ for i, cell in enumerate(row):
124
+ if i < num_cols:
125
+ col_widths[i] = max(col_widths[i], len(cell))
126
+
127
+ for row in rows:
128
+ parts = []
129
+ for i in range(num_cols):
130
+ val = row[i] if i < len(row) else ""
131
+ parts.append(val.ljust(col_widths[i]))
132
+ print(" ".join(parts))
133
+
134
+
135
+ def print_usage():
136
+ """Print usage information."""
137
+ print(__doc__.strip())
138
+
139
+
140
+ def main():
141
+ args = sys.argv[1:]
142
+
143
+ filepath = None
144
+ lines = 10
145
+ column_names = None
146
+ output_format = "csv"
147
+ has_header = True
148
+
149
+ i = 0
150
+ while i < len(args):
151
+ arg = args[i]
152
+ if arg in ("-h", "--help"):
153
+ print_usage()
154
+ return
155
+ elif arg in ("-n", "--lines") and i + 1 < len(args):
156
+ try:
157
+ lines = int(args[i + 1])
158
+ if lines < 0:
159
+ print("Error: --lines/-n requires a non-negative integer", file=sys.stderr)
160
+ sys.exit(1)
161
+ except ValueError:
162
+ print("Error: --lines/-n requires an integer", file=sys.stderr)
163
+ sys.exit(1)
164
+ i += 2
165
+ elif arg in ("-c", "--columns") and i + 1 < len(args):
166
+ column_names = [c.strip() for c in args[i + 1].split(",")]
167
+ i += 2
168
+ elif arg in ("-f", "--format") and i + 1 < len(args):
169
+ fmt = args[i + 1].lower()
170
+ if fmt not in ("csv", "table"):
171
+ print(f"Error: --format/-f must be 'csv' or 'table', got '{fmt}'", file=sys.stderr)
172
+ sys.exit(1)
173
+ output_format = fmt
174
+ i += 2
175
+ elif arg == "--no-header":
176
+ has_header = False
177
+ i += 1
178
+ elif arg.startswith("-"):
179
+ print(f"Error: unknown option '{arg}'. Use --help for usage.", file=sys.stderr)
180
+ sys.exit(1)
181
+ else:
182
+ if filepath is not None:
183
+ print(f"Error: unexpected argument '{arg}'. Only one file path allowed.", file=sys.stderr)
184
+ sys.exit(1)
185
+ filepath = arg
186
+ i += 1
187
+
188
+ # Read input
189
+ content, source_name = read_input(filepath)
190
+
191
+ if not content.strip():
192
+ print("(empty file)")
193
+ sys.exit(0)
194
+
195
+ # Parse CSV
196
+ rows = parse_csv(content)
197
+
198
+ if not rows:
199
+ print("(no data)")
200
+ sys.exit(0)
201
+
202
+ total_rows = len(rows)
203
+
204
+ # Determine data rows based on header
205
+ if has_header and total_rows > 0:
206
+ header = rows[0]
207
+ data_rows = rows[1:]
208
+ else:
209
+ header = None
210
+ data_rows = rows
211
+
212
+ # Slice first N data rows
213
+ if lines > 0 and lines < len(data_rows):
214
+ data_rows = data_rows[:lines]
215
+
216
+ # Reconstruct rows with optional header
217
+ if header is not None:
218
+ display_rows = [header] + data_rows
219
+ else:
220
+ display_rows = data_rows
221
+
222
+ # Filter columns if requested
223
+ if column_names:
224
+ display_rows = filter_columns(display_rows, column_names, has_header)
225
+
226
+ # Output
227
+ if output_format == "csv":
228
+ format_csv(display_rows)
229
+ else:
230
+ format_table(display_rows)
231
+
232
+
233
+ if __name__ == "__main__":
234
+ main()
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ csv-sort — Sort CSV files by column.
4
+
5
+ Usage:
6
+ csv-sort [--column COL] [--reverse] [--numeric] [FILE]
7
+
8
+ Arguments:
9
+ FILE Input CSV file (reads from stdin if omitted)
10
+
11
+ Options:
12
+ -c, --column COL Column name or 1-based index to sort by (default: first column)
13
+ -r, --reverse Sort in descending order
14
+ -n, --numeric Sort values as numbers instead of text
15
+ -h, --help Show this help message and exit
16
+
17
+ Examples:
18
+ csv-sort data.csv
19
+ csv-sort -c 2 -r data.csv
20
+ csv-sort -c "name" -n < data.csv
21
+ cat data.csv | csv-sort -c "age" -n -r
22
+ """
23
+
24
+ import csv
25
+ import sys
26
+
27
+
28
+ def main():
29
+ args = sys.argv[1:]
30
+
31
+ # Parse help
32
+ if '-h' in args or '--help' in args:
33
+ print((__doc__ or '').strip())
34
+ return
35
+
36
+ # Parse --column / -c
37
+ column = None
38
+ if '--column' in args:
39
+ idx = args.index('--column')
40
+ if idx + 1 < len(args):
41
+ column = args[idx + 1]
42
+ args = args[:idx] + args[idx + 2:]
43
+ elif '-c' in args:
44
+ idx = args.index('-c')
45
+ if idx + 1 < len(args):
46
+ column = args[idx + 1]
47
+ args = args[:idx] + args[idx + 2:]
48
+
49
+ # Parse flags
50
+ reverse = '--reverse' in args or '-r' in args
51
+ numeric = '--numeric' in args or '-n' in args
52
+ args = [a for a in args if a not in ('--reverse', '-r', '--numeric', '-n')]
53
+
54
+ # Remaining positional arg is file path (optional)
55
+ filepath = args[0] if args else None
56
+
57
+ try:
58
+ if filepath:
59
+ with open(filepath, newline='') as f:
60
+ reader = csv.reader(f)
61
+ rows = list(reader)
62
+ else:
63
+ reader = csv.reader(sys.stdin)
64
+ rows = list(reader)
65
+ except Exception as e:
66
+ print(f"Error: {e}", file=sys.stderr)
67
+ sys.exit(1)
68
+
69
+ if not rows:
70
+ sys.exit(0)
71
+
72
+ # Separate header from data
73
+ header = rows[0]
74
+ data = rows[1:]
75
+
76
+ # Determine column index
77
+ if column is None:
78
+ col_idx = 0
79
+ else:
80
+ try:
81
+ col_idx = int(column) - 1 # 1-based to 0-based
82
+ except ValueError:
83
+ # Column is a name — find it in the header
84
+ try:
85
+ col_idx = header.index(column)
86
+ except ValueError:
87
+ print(f"Error: column '{column}' not found in header: {header}", file=sys.stderr)
88
+ sys.exit(1)
89
+
90
+ if col_idx < 0:
91
+ print(f"Error: column index must be 1 or greater", file=sys.stderr)
92
+ sys.exit(1)
93
+
94
+ # Sort
95
+ try:
96
+ if numeric:
97
+ data.sort(key=lambda row: _safe_num(row[col_idx]), reverse=reverse)
98
+ else:
99
+ data.sort(key=lambda row: row[col_idx] if col_idx < len(row) else '', reverse=reverse)
100
+ except IndexError:
101
+ print(f"Error: column index {col_idx + 1} exceeds row width", file=sys.stderr)
102
+ sys.exit(1)
103
+ except Exception as e:
104
+ print(f"Error during sort: {e}", file=sys.stderr)
105
+ sys.exit(1)
106
+
107
+ # Write output
108
+ writer = csv.writer(sys.stdout)
109
+ writer.writerow(header)
110
+ writer.writerows(data)
111
+
112
+
113
+ def _safe_num(val):
114
+ """Convert a string to float for numeric sorting, with fallback."""
115
+ try:
116
+ return float(val)
117
+ except (ValueError, TypeError):
118
+ return float('inf')
119
+
120
+
121
+ TOOL_META = {"name": "csv-sort", "func": "main", "desc": "Sort CSV files by column"}
122
+
123
+
124
+ if __name__ == '__main__':
125
+ main()