reposnap 0.4.0__py3-none-any.whl → 0.5.1__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.
@@ -19,6 +19,8 @@ class ProjectController:
19
19
  self.args: object = args
20
20
  self.file_tree: Optional[FileTree] = None
21
21
  self.gitignore_patterns: List[str] = []
22
+ self.include_patterns: List[str] = args.include if args and hasattr(args, 'include') else []
23
+ self.exclude_patterns: List[str] = args.exclude if args and hasattr(args, 'exclude') else []
22
24
  if self.root_dir:
23
25
  self.gitignore_patterns = self._load_gitignore_patterns()
24
26
 
@@ -40,6 +42,30 @@ class ProjectController:
40
42
  git_files: List[Path] = git_repo.get_git_files()
41
43
  self.logger.debug(f"Git files before filtering: {git_files}")
42
44
 
45
+ # Adjust patterns
46
+ def adjust_patterns(patterns):
47
+ adjusted = []
48
+ for pattern in patterns:
49
+ if '*' in pattern or '?' in pattern or '[' in pattern:
50
+ adjusted.append(pattern)
51
+ else:
52
+ adjusted.append(f'*{pattern}*')
53
+ return adjusted
54
+
55
+ # Apply include patterns
56
+ if self.include_patterns:
57
+ adjusted_include_patterns = adjust_patterns(self.include_patterns)
58
+ include_spec = pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, adjusted_include_patterns)
59
+ git_files = [f for f in git_files if include_spec.match_file(f.as_posix())]
60
+ self.logger.debug(f"Git files after include patterns: {git_files}")
61
+
62
+ # Apply exclude patterns
63
+ if self.exclude_patterns:
64
+ adjusted_exclude_patterns = adjust_patterns(self.exclude_patterns)
65
+ exclude_spec = pathspec.PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, adjusted_exclude_patterns)
66
+ git_files = [f for f in git_files if not exclude_spec.match_file(f.as_posix())]
67
+ self.logger.debug(f"Git files after exclude patterns: {git_files}")
68
+
43
69
  self.logger.info("Building tree structure.")
44
70
  file_system: FileSystem = FileSystem(self.root_dir)
45
71
  tree_structure: dict = file_system.build_tree_structure(git_files)
@@ -58,7 +58,11 @@ class MarkdownGenerator:
58
58
  self.logger.debug(f"File not found: {file_path}. Skipping.")
59
59
  continue
60
60
 
61
- self._write_file_content(file_path, relative_path.as_posix())
61
+ try:
62
+ self._write_file_content(file_path, relative_path.as_posix())
63
+ except UnicodeDecodeError as e:
64
+ self.logger.error(f"UnicodeDecodeError for file {file_path}: {e}")
65
+
62
66
 
63
67
  def _write_file_content(self, file_path: Path, relative_path: str) -> None:
64
68
  """
@@ -13,6 +13,12 @@ def main():
13
13
  help='Only include the file structure without content.')
14
14
  parser.add_argument('--debug', action='store_true', help='Enable debug-level logging.')
15
15
 
16
+ # New arguments for include and exclude patterns
17
+ parser.add_argument('-i', '--include', nargs='*', default=[],
18
+ help='File/folder patterns to include.')
19
+ parser.add_argument('-e', '--exclude', nargs='*', default=[],
20
+ help='File/folder patterns to exclude.')
21
+
16
22
  args = parser.parse_args()
17
23
 
18
24
  log_level = logging.DEBUG if args.debug else logging.INFO
@@ -21,5 +27,6 @@ def main():
21
27
  controller = ProjectController(args)
22
28
  controller.run()
23
29
 
30
+
24
31
  if __name__ == "__main__":
25
32
  main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: reposnap
3
- Version: 0.4.0
3
+ Version: 0.5.1
4
4
  Summary: Generate a Markdown file with all contents of your project
5
5
  Author: agoloborodko
6
6
  License-File: LICENSE
@@ -24,6 +24,7 @@ Description-Content-Type: text/markdown
24
24
  - **Syntax Highlighting**: Includes syntax highlighting for known file types in the generated Markdown file.
25
25
  - **Structure Only Option**: The `--structure-only` flag can be used to generate the Markdown file with just the directory structure, omitting the contents of the files.
26
26
  - **Gitignore Support**: Automatically respects `.gitignore` patterns to exclude files and directories.
27
+ - **Include and Exclude Patterns**: Use `--include` and `--exclude` to specify patterns for files and directories to include or exclude.
27
28
 
28
29
  ## Installation
29
30
 
@@ -38,7 +39,7 @@ Alternatively, you can clone the repository and install the required dependencie
38
39
  ```bash
39
40
  git clone https://github.com/username/reposnap.git
40
41
  cd reposnap
41
- pip install -r requirements.txt
42
+ pip install -r requirements.lock
42
43
  ```
43
44
 
44
45
  ## Usage
@@ -48,7 +49,7 @@ pip install -r requirements.txt
48
49
  To use `reposnap` from the command line, run it with the following options:
49
50
 
50
51
  ```bash
51
- reposnap [-h] [-o OUTPUT] [--structure-only] [--debug] path
52
+ reposnap [-h] [-o OUTPUT] [--structure-only] [--debug] [-i INCLUDE [INCLUDE ...]] [-e EXCLUDE [EXCLUDE ...]] path
52
53
  ```
53
54
 
54
55
  - `path`: Path to the Git repository or subdirectory.
@@ -56,6 +57,19 @@ reposnap [-h] [-o OUTPUT] [--structure-only] [--debug] path
56
57
  - `-o, --output`: The name of the output Markdown file. Defaults to `output.md`.
57
58
  - `--structure-only`: Generate a Markdown file that includes only the project structure, without file contents.
58
59
  - `--debug`: Enable debug-level logging.
60
+ - `-i, --include`: File/folder patterns to include. For example, `-i "*.py"` includes only Python files.
61
+ - `-e, --exclude`: File/folder patterns to exclude. For example, `-e "*.md"` excludes all Markdown files.
62
+
63
+ #### Pattern Matching
64
+
65
+ - **Pattern Interpretation**: Patterns follow gitignore-style syntax but with a twist.
66
+ - **Patterns without Wildcards**: If a pattern does not contain any wildcard characters (`*`, `?`, or `[`), it is treated as `*pattern*`. This means it will match any file or directory containing `pattern` in its name.
67
+ - **Patterns with Wildcards**: If a pattern contains wildcard characters, it retains its original behavior.
68
+
69
+ - **Examples**:
70
+ - `-e "gui"`: Excludes any files or directories containing `"gui"` in their names.
71
+ - `-i "*.py"`: Includes only files ending with `.py`.
72
+ - `-e "*.test.*"`: Excludes files with `.test.` in their names.
59
73
 
60
74
  #### Examples
61
75
 
@@ -71,10 +85,22 @@ reposnap [-h] [-o OUTPUT] [--structure-only] [--debug] path
71
85
  reposnap my_project/ --structure-only
72
86
  ```
73
87
 
74
- 3. **Generate a Markdown file excluding certain files and directories**:
88
+ 3. **Generate a Markdown file including only Python files**:
89
+
90
+ ```bash
91
+ reposnap my_project/ -i "*.py"
92
+ ```
93
+
94
+ 4. **Generate a Markdown file excluding certain files and directories**:
95
+
96
+ ```bash
97
+ reposnap my_project/ -e "tests" -e "*.md"
98
+ ```
99
+
100
+ 5. **Exclude files and directories containing a substring**:
75
101
 
76
102
  ```bash
77
- reposnap my_project/ -o output.md
103
+ reposnap my_project/ -e "gui"
78
104
  ```
79
105
 
80
106
  ### Graphical User Interface
@@ -1,19 +1,19 @@
1
1
  reposnap/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  reposnap/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- reposnap/controllers/project_controller.py,sha256=JVxCc5MH_GOvEwTAaasuqxd1XSgKFbdQDjUEwmg4pUk,4211
3
+ reposnap/controllers/project_controller.py,sha256=hDYNLE_OtusAZOb6sKyvSFtbc7j-DUuYcmFST7U5Dao,5638
4
4
  reposnap/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  reposnap/core/file_system.py,sha256=82gwvmgrsWf63paMrIz-Z0eqIjbqt9_-vujdXlJJoFE,1074
6
6
  reposnap/core/git_repo.py,sha256=2u_ILkV-Ur7qr1WHmHM2yg44Ggft61RsdbZLsZaQ5NU,1256
7
- reposnap/core/markdown_generator.py,sha256=DkH7Gdo-fWevSyp9nqIyOG6qVOT6kk36xndR6X5vskM,3148
7
+ reposnap/core/markdown_generator.py,sha256=Ld6ix4gzkLJJyeUoWHwhpbAf3DvEC5E0S1DykYnLGnQ,3297
8
8
  reposnap/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- reposnap/interfaces/cli.py,sha256=fpJBTmGw8A8dVLdYEtERV7L2P-8lzBlmwIvD3NhTD-Q,985
9
+ reposnap/interfaces/cli.py,sha256=tq9OfVE1NvUYrsdr2ewx6nBhG76k8E-yucwVgTo-LM8,1302
10
10
  reposnap/interfaces/gui.py,sha256=pzWQbW55gBNZu4tXRdBFic39upGtYxew91FSiEvalj0,5421
11
11
  reposnap/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  reposnap/models/file_tree.py,sha256=SQ1cKW066uh1F1BcF8AXuw4Q-l6rkybxjdJEcLFjewg,3052
13
13
  reposnap/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  reposnap/utils/path_utils.py,sha256=7072816LCP8Q8XBydn0iknmfrObPO_-2rFqpbAvPrjY,501
15
- reposnap-0.4.0.dist-info/METADATA,sha256=rOGqK2qsMgpPeYzwrxn0p5trlPFSs0kFqVqMhZBi4KM,3929
16
- reposnap-0.4.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
17
- reposnap-0.4.0.dist-info/entry_points.txt,sha256=o3GyO7bpR0dujPCjsvvZMPv4pXNJlFwD49_pA1r5FOA,102
18
- reposnap-0.4.0.dist-info/licenses/LICENSE,sha256=Aj7WCYBXi98pvi723HPn4GDRyjxToNWb3PC6j1_lnPk,1069
19
- reposnap-0.4.0.dist-info/RECORD,,
15
+ reposnap-0.5.1.dist-info/METADATA,sha256=D6PPKKJAUGFYWK02v1_2WhvGVXUIFv_OoZBOlv9-AUw,5241
16
+ reposnap-0.5.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
17
+ reposnap-0.5.1.dist-info/entry_points.txt,sha256=o3GyO7bpR0dujPCjsvvZMPv4pXNJlFwD49_pA1r5FOA,102
18
+ reposnap-0.5.1.dist-info/licenses/LICENSE,sha256=Aj7WCYBXi98pvi723HPn4GDRyjxToNWb3PC6j1_lnPk,1069
19
+ reposnap-0.5.1.dist-info/RECORD,,