@@ -31,51 +31,70 @@ def is_ignored_by_gitignore(path):
3131 return False
3232
3333
34- def _list_unignored (base_dir , only_files , path ):
35- base , dirs , files = next (os .walk (path ))
36- for f in files :
37- ff = os .path .join (base , f )
38- if f == ".gitignore" :
39- yield ff
40- elif not is_ignored_by_gitignore (ff ):
41- yield ff
42- for d in dirs :
43- if d == ".git" :
34+ def _list_dirs (path ):
35+ for base , _ , _ in os .walk (path ):
36+ if base == path :
4437 continue
45- dd = os .path .join (base , d )
46- if not is_ignored_by_gitignore (dd ):
47- if not only_files :
48- yield dd
49- yield from _list_unignored (base_dir , only_files , dd )
38+ if "/.git/" in os .path .normpath (base ) + "/" :
39+ continue
40+ yield base
5041
5142
52- def _list_all (path , only_files ):
53- for base , dirnames , filenames in os .walk (path ):
54- for filename in filenames :
55- yield os .path .join (base , filename )
56- if not only_files :
57- for dirname in dirnames :
58- if dirname == ".git" :
59- continue
60- yield os .path .join (base , dirname )
43+ def _list_unignored (base_dir , only_files , only_dirs , path ):
44+ if only_dirs :
45+ yield from _list_dirs (path )
46+ else :
47+ base , dirs , files = next (os .walk (path ))
48+ for f in files :
49+ ff = os .path .join (base , f )
50+ if f == ".gitignore" :
51+ yield ff
52+ elif not is_ignored_by_gitignore (ff ):
53+ yield ff
54+ for d in dirs :
55+ if d == ".git" :
56+ continue
57+ dd = os .path .join (base , d )
58+ if not is_ignored_by_gitignore (dd ):
59+ if not only_files :
60+ yield dd
61+ yield from _list_unignored (base_dir , only_files , only_dirs , dd )
62+
63+
64+ def _list_all (path , only_files , only_dirs ):
65+ if only_dirs :
66+ yield from _list_dirs (path )
67+ else :
68+ for base , dirnames , filenames in os .walk (path ):
69+ for filename in filenames :
70+ yield os .path .join (base , filename )
71+ if not only_files :
72+ for dirname in dirnames :
73+ if dirname == ".git" :
74+ continue
75+ yield os .path .join (base , dirname )
6176
6277
63- def ls_recursive (path , relative = False , exclude_gitignore = False , only_files = False ):
78+ def ls_recursive (path , relative = False , exclude_gitignore = False , only_files = False , only_dirs = False ):
6479 """
6580 Always skips .git folder
6681 :param path: The path to list files (or dirs) inside it
6782 :param relative: If True, returned paths will be relative to `path`
6883 :param exclude_gitignore: If True, only paths that are not ignored by .gitignore files will be returned.
6984 In this case, `path` must be inside a git repo.
7085 :param only_files: If True, only files will be returned (skips directories)
86+ :param only_dirs: If True, only directories will be returned (skips files)
7187 :return: A list of paths inside `path`
7288 """
89+ if only_dirs and only_files :
90+ raise Exception ("Only one of `only_dirs` and `only_files` can be True" )
7391 if exclude_gitignore :
7492 if not is_inside_git_repo (path ):
7593 raise NotGitRepoException
76- absolute_paths = list (_list_unignored (path , only_files , path ))
94+
95+ absolute_paths = list (_list_unignored (path , only_files , only_dirs , path ))
7796 else :
78- absolute_paths = list (_list_all (path , only_files ))
97+ absolute_paths = list (_list_all (path , only_files , only_dirs ))
7998 if relative :
8099 return [os .path .relpath (i , start = path ) for i in absolute_paths ]
81100 else :
@@ -94,7 +113,7 @@ def get_comment_style(commented_line, scb):
94113 raise Exception
95114 ss , ff = comment_parts [0 ].lstrip (), comment_parts [1 ].rstrip ()
96115 s , f = ss .rstrip (), ff .lstrip ()
97- return [s , ss [len (s ) :], ff [: - len (f )], f ]
116+ return [s , ss [len (s ):], ff [: - len (f )], f ]
98117
99118
100119def uncomment (commented_line , comment_style ):
0 commit comments