sunholo 0.59.7__py3-none-any.whl → 0.60.0__py3-none-any.whl

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.
sunholo/cli/cli.py CHANGED
@@ -3,6 +3,8 @@ import argparse
3
3
  from .configs import setup_list_configs_subparser
4
4
  from .deploy import setup_deploy_subparser
5
5
  from .cli_init import setup_init_subparser
6
+ from .merge_texts import setup_merge_text_subparser
7
+
6
8
 
7
9
  def main(args=None):
8
10
  """
@@ -21,12 +23,14 @@ def main(args=None):
21
23
  dest='command',
22
24
  required=True)
23
25
 
24
- # Setup deploy command
26
+ # deploy command
25
27
  setup_deploy_subparser(subparsers)
26
28
  # Setup list-configs command
27
29
  setup_list_configs_subparser(subparsers)
28
- # init
30
+ # init command
29
31
  setup_init_subparser(subparsers)
32
+ # merge-text command
33
+ setup_merge_text_subparser(subparsers)
30
34
 
31
35
  args = parser.parse_args(args)
32
36
 
sunholo/cli/configs.py CHANGED
@@ -113,7 +113,7 @@ def setup_list_configs_subparser(subparsers):
113
113
  subparsers = parser.add_subparsers()
114
114
  setup_list_configs_subparser(subparsers)
115
115
  """
116
- list_configs_parser = subparsers.add_parser('list-configs', help='Lists all configuration files and their details e.g. `sunholo list-configs --kind=vacConfig --vac=edmonbrain`')
116
+ list_configs_parser = subparsers.add_parser('list-configs', help='Lists all configuration files and their details')
117
117
  list_configs_parser.add_argument('--kind', help='Filter configurations by kind e.g. `--kind=vacConfig`')
118
118
  list_configs_parser.add_argument('--vac', help='Filter configurations by VAC name e.g. `--vac=edmonbrain`')
119
119
  list_configs_parser.add_argument('--validate', action='store_true', help='Validate the configuration files.')
@@ -0,0 +1,41 @@
1
+ import os
2
+ from pprint import pprint
3
+
4
+ from ..utils.big_context import load_gitignore_patterns, merge_text_files
5
+
6
+ def setup_merge_text_subparser(subparsers):
7
+ """
8
+ Sets up an argparse subparser for the 'merge-text' command.
9
+
10
+ Args:
11
+ subparsers: The subparsers object from argparse.ArgumentParser().
12
+ """
13
+ merge_text_parser = subparsers.add_parser('merge-text', help='Merge text files from a source folder into a single output file.')
14
+ merge_text_parser.add_argument('source_folder', help='Folder containing the text files.')
15
+ merge_text_parser.add_argument('output_file', help='Output file to write the merged text.')
16
+ merge_text_parser.add_argument('--gitignore', help='Path to .gitignore file to exclude patterns.', default=None)
17
+ merge_text_parser.add_argument('--output_tree', action='store_true', help='Set to output the file tree in the console after merging', default=None)
18
+
19
+ merge_text_parser.set_defaults(func=merge_text_files_command)
20
+
21
+ def merge_text_files_command(args):
22
+ """
23
+ Command to merge text files based on the provided arguments.
24
+
25
+ Args:
26
+ args: Command-line arguments.
27
+ """
28
+ gitignore_path = os.path.join(args.source_folder, '.gitignore') if not args.gitignore else args.gitignore
29
+
30
+ if os.path.exists(gitignore_path):
31
+ patterns = load_gitignore_patterns(gitignore_path)
32
+ print(f"Ignoring patterns from {gitignore_path}")
33
+ else:
34
+ patterns = [] # Empty list if no .gitignore
35
+
36
+ print(f"Merging text files within {args.source_folder} to {args.output_file}")
37
+ file_tree = merge_text_files(args.source_folder, args.output_file, patterns)
38
+ print(f"OK: Merged files available in {args.output_file}")
39
+ if args.output_tree:
40
+ print(f"==File Tree for {args.source_folder}")
41
+ pprint(file_tree)
@@ -1,4 +1,5 @@
1
1
  import os
2
+ from fnmatch import fnmatch
2
3
 
3
4
  def has_text_extension(file_path):
4
5
  """
@@ -42,6 +43,7 @@ def load_gitignore_patterns(gitignore_path):
42
43
  """
43
44
  with open(gitignore_path, 'r') as f:
44
45
  patterns = [line.strip() for line in f if line.strip() and not line.startswith('#')]
46
+ patterns.extend(["*.git/*", "*.terraform/*"])
45
47
  return patterns
46
48
 
47
49
  def should_ignore(file_path, patterns):
@@ -59,13 +61,15 @@ def should_ignore(file_path, patterns):
59
61
  >>> should_ignore("path/to/file.txt", ["*.txt", "node_modules/"])
60
62
  True
61
63
  """
62
- from fnmatch import fnmatch
63
64
  rel_path = os.path.relpath(file_path)
65
+
64
66
  for pattern in patterns:
65
67
  if fnmatch(rel_path, pattern) or fnmatch(os.path.basename(rel_path), pattern):
66
68
  return True
69
+
67
70
  return False
68
71
 
72
+
69
73
  def build_file_tree(source_folder, patterns):
70
74
  """
71
75
  Build a hierarchical file tree structure of a directory, ignoring files and directories in .gitignore.
@@ -112,6 +116,7 @@ def merge_text_files(source_folder, output_file, patterns):
112
116
  file_tree = build_file_tree(source_folder, patterns)
113
117
  with open(output_file, 'w', encoding='utf-8') as outfile:
114
118
  for root, dirs, files in os.walk(source_folder):
119
+ print(f"- merging {root}...")
115
120
  # Filter out ignored directories
116
121
  dirs[:] = [d for d in dirs if not should_ignore(os.path.join(root, d), patterns)]
117
122
  # Filter out ignored files
@@ -119,6 +124,8 @@ def merge_text_files(source_folder, output_file, patterns):
119
124
 
120
125
  for file_name in files:
121
126
  file_path = os.path.join(root, file_name)
127
+ if file_path == output_file:
128
+ continue
122
129
  if has_text_extension(file_path):
123
130
  try:
124
131
  with open(file_path, 'r', encoding='utf-8') as infile:
@@ -129,6 +136,8 @@ def merge_text_files(source_folder, output_file, patterns):
129
136
  print(f"Skipping file (cannot read as text): {file_path}")
130
137
  outfile.write("\n--- File Tree ---\n")
131
138
  outfile.write("\n".join(file_tree))
139
+
140
+ return file_tree
132
141
 
133
142
  # Example usage
134
143
  if __name__ == "__main__":
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sunholo
3
- Version: 0.59.7
3
+ Version: 0.60.0
4
4
  Summary: Large Language Model DevOps - a package to help deploy LLMs to the Cloud.
5
5
  Home-page: https://github.com/sunholo-data/sunholo-py
6
- Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.59.7.tar.gz
6
+ Download-URL: https://github.com/sunholo-data/sunholo-py/archive/refs/tags/v0.60.0.tar.gz
7
7
  Author: Holosun ApS
8
8
  Author-email: multivac@sunholo.com
9
9
  License: Apache License, Version 2.0
@@ -32,10 +32,11 @@ sunholo/chunker/pdfs.py,sha256=daCZ1xjn1YvxlifIyxskWNpLJLe-Q9D_Jq12MWx3tZo,2473
32
32
  sunholo/chunker/publish.py,sha256=PoT8q3XJeFCg10WrLkYhuaaXIrGVkvUD3-R9IfoWoH4,2703
33
33
  sunholo/chunker/splitter.py,sha256=FLkDhkePkg_zGQpFBK13Cznw575D-Rf9pcaCpc1HUxY,6726
34
34
  sunholo/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- sunholo/cli/cli.py,sha256=rcO1hMthy5nWC_5sOHqRm7ut70c9JfxFTSjFRBNYuYg,1248
35
+ sunholo/cli/cli.py,sha256=1fWvRzfise-DD7AXMx_-9IaabVR4T9FPzn95qQ4Bk20,1371
36
36
  sunholo/cli/cli_init.py,sha256=WReZuMQwDfkRUvssYT7TirUoG6SiT1dTDol8nLI8O70,3418
37
- sunholo/cli/configs.py,sha256=jHCNz_rANlQI2ZCWnlgJu5QwQc-a_Koi9Hm3XHjHEpE,4608
37
+ sunholo/cli/configs.py,sha256=QUM9DvKOdZmEQRM5uI3Nh887T0YDiSMr7O240zTLqws,4546
38
38
  sunholo/cli/deploy.py,sha256=zxdwUsRTRMC8U5vyRv0JiKBLFn84Ug_Tc88-_h9hJSs,1609
39
+ sunholo/cli/merge_texts.py,sha256=U9vdMwKmcPoc6iPOWX5MKSxn49dNGbNzVLw8ui5PhEU,1823
39
40
  sunholo/components/__init__.py,sha256=RJGNEihwvRIiDScKis04RHJv4yZGI1UpXlOmuCptNZI,208
40
41
  sunholo/components/llm.py,sha256=T4we3tGmqUj4tPwxQr9M6AXv_BALqZV_dRSvINan-oU,10374
41
42
  sunholo/components/prompt.py,sha256=eZSghXkIlRzXiSrzgkG7e5ytUYq6R6LV-qjHU8jStig,6353
@@ -84,16 +85,16 @@ sunholo/streaming/streaming.py,sha256=9z6pXINEopuL_Z1RnmgXAoZJum9dzyuOxqYtEYnjf8
84
85
  sunholo/summarise/__init__.py,sha256=MZk3dblUMODcPb1crq4v-Z508NrFIpkSWNf9FIO8BcU,38
85
86
  sunholo/summarise/summarise.py,sha256=C3HhjepTjUhUC8FLk4jMQIBvq1BcORniwuTFHjPVhVo,3784
86
87
  sunholo/utils/__init__.py,sha256=G11nN_6ATjxpuMfG_BvcUr9UU8onPIgkpTK6CjOcbr8,48
87
- sunholo/utils/big_context.py,sha256=qHYtds4Ecf9eZRHVqXho4_q8Je7HD44-vS6RJ6s9Z0Q,5387
88
+ sunholo/utils/big_context.py,sha256=gJIP7_ZL-YSLhOMq8jmFTMqH1wq8eB1NK7oKPeZAq2s,5578
88
89
  sunholo/utils/config.py,sha256=WIcJstLkQsM8iMCl_GBpgYdrSWIcnnCJ_uOFHIQX1g8,8500
89
90
  sunholo/utils/config_schema.py,sha256=Wv-ncitzljOhgbDaq9qnFqH5LCuxNv59dTGDWgd1qdk,4189
90
91
  sunholo/utils/gcp.py,sha256=B2G1YKjeD7X9dqO86Jrp2vPuFwZ223Xl5Tg09Ndw-oc,5760
91
92
  sunholo/utils/parsers.py,sha256=OrHmASqIbI45atVOhiGodgLvnfrzkvVzyHnSvAXD89I,3841
92
93
  sunholo/vertex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
94
  sunholo/vertex/init_vertex.py,sha256=JDMUaBRdednzbKF-5p33qqLit2LMsvgvWW-NRz0AqO0,1801
94
- sunholo-0.59.7.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
95
- sunholo-0.59.7.dist-info/METADATA,sha256=VIsL_Vee2i1tD_9DnxhhpT20IP-l8iAnyXv_A7y8o44,7903
96
- sunholo-0.59.7.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
97
- sunholo-0.59.7.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
98
- sunholo-0.59.7.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
99
- sunholo-0.59.7.dist-info/RECORD,,
95
+ sunholo-0.60.0.dist-info/LICENSE.txt,sha256=SdE3QjnD3GEmqqg9EX3TM9f7WmtOzqS1KJve8rhbYmU,11345
96
+ sunholo-0.60.0.dist-info/METADATA,sha256=jPNGU1h7W5pvMUmp_noLhzmkT01vru1nmSM10MA1SMU,7903
97
+ sunholo-0.60.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
98
+ sunholo-0.60.0.dist-info/entry_points.txt,sha256=bZuN5AIHingMPt4Ro1b_T-FnQvZ3teBes-3OyO0asl4,49
99
+ sunholo-0.60.0.dist-info/top_level.txt,sha256=wt5tadn5--5JrZsjJz2LceoUvcrIvxjHJe-RxuudxAk,8
100
+ sunholo-0.60.0.dist-info/RECORD,,