diff options
author | Gavin Mak <gavinmak@google.com> | 2023-03-11 06:46:20 +0000 |
---|---|---|
committer | LUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-03-22 17:46:28 +0000 |
commit | ea2e330e43c182dc16b0111ebc69ee5a71ee4ce1 (patch) | |
tree | dc33ba0e56825b3e007d0589891756724725a465 /subcmds/status.py | |
parent | 1604cf255f8c1786a23388db6d5277ac7949a24a (diff) | |
download | git-repo-ea2e330e43c182dc16b0111ebc69ee5a71ee4ce1.tar.gz |
Format codebase with black and check formatting in CQ
Apply rules set by https://gerrit-review.googlesource.com/c/git-repo/+/362954/ across the codebase and fix any lingering errors caught
by flake8. Also check black formatting in run_tests (and CQ).
Bug: b/267675342
Change-Id: I972d77649dac351150dcfeb1cd1ad0ea2efc1956
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/363474
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Gavin Mak <gavinmak@google.com>
Commit-Queue: Gavin Mak <gavinmak@google.com>
Diffstat (limited to 'subcmds/status.py')
-rw-r--r-- | subcmds/status.py | 239 |
1 files changed, 129 insertions, 110 deletions
diff --git a/subcmds/status.py b/subcmds/status.py index 572c72f7..6e0026f9 100644 --- a/subcmds/status.py +++ b/subcmds/status.py | |||
@@ -24,12 +24,12 @@ import platform_utils | |||
24 | 24 | ||
25 | 25 | ||
26 | class Status(PagedCommand): | 26 | class Status(PagedCommand): |
27 | COMMON = True | 27 | COMMON = True |
28 | helpSummary = "Show the working tree status" | 28 | helpSummary = "Show the working tree status" |
29 | helpUsage = """ | 29 | helpUsage = """ |
30 | %prog [<project>...] | 30 | %prog [<project>...] |
31 | """ | 31 | """ |
32 | helpDescription = """ | 32 | helpDescription = """ |
33 | '%prog' compares the working tree to the staging area (aka index), | 33 | '%prog' compares the working tree to the staging area (aka index), |
34 | and the most recent commit on this branch (HEAD), in each project | 34 | and the most recent commit on this branch (HEAD), in each project |
35 | specified. A summary is displayed, one line per file where there | 35 | specified. A summary is displayed, one line per file where there |
@@ -76,109 +76,128 @@ the following meanings: | |||
76 | d: deleted ( in index, not in work tree ) | 76 | d: deleted ( in index, not in work tree ) |
77 | 77 | ||
78 | """ | 78 | """ |
79 | PARALLEL_JOBS = DEFAULT_LOCAL_JOBS | 79 | PARALLEL_JOBS = DEFAULT_LOCAL_JOBS |
80 | 80 | ||
81 | def _Options(self, p): | 81 | def _Options(self, p): |
82 | p.add_option('-o', '--orphans', | 82 | p.add_option( |
83 | dest='orphans', action='store_true', | 83 | "-o", |
84 | help="include objects in working directory outside of repo projects") | 84 | "--orphans", |
85 | 85 | dest="orphans", | |
86 | def _StatusHelper(self, quiet, local, project): | 86 | action="store_true", |
87 | """Obtains the status for a specific project. | 87 | help="include objects in working directory outside of repo " |
88 | 88 | "projects", | |
89 | Obtains the status for a project, redirecting the output to | 89 | ) |
90 | the specified object. | 90 | |
91 | 91 | def _StatusHelper(self, quiet, local, project): | |
92 | Args: | 92 | """Obtains the status for a specific project. |
93 | quiet: Where to output the status. | 93 | |
94 | local: a boolean, if True, the path is relative to the local | 94 | Obtains the status for a project, redirecting the output to |
95 | (sub)manifest. If false, the path is relative to the | 95 | the specified object. |
96 | outermost manifest. | 96 | |
97 | project: Project to get status of. | 97 | Args: |
98 | 98 | quiet: Where to output the status. | |
99 | Returns: | 99 | local: a boolean, if True, the path is relative to the local |
100 | The status of the project. | 100 | (sub)manifest. If false, the path is relative to the outermost |
101 | """ | 101 | manifest. |
102 | buf = io.StringIO() | 102 | project: Project to get status of. |
103 | ret = project.PrintWorkTreeStatus(quiet=quiet, output_redir=buf, | 103 | |
104 | local=local) | 104 | Returns: |
105 | return (ret, buf.getvalue()) | 105 | The status of the project. |
106 | 106 | """ | |
107 | def _FindOrphans(self, dirs, proj_dirs, proj_dirs_parents, outstring): | 107 | buf = io.StringIO() |
108 | """find 'dirs' that are present in 'proj_dirs_parents' but not in 'proj_dirs'""" | 108 | ret = project.PrintWorkTreeStatus( |
109 | status_header = ' --\t' | 109 | quiet=quiet, output_redir=buf, local=local |
110 | for item in dirs: | 110 | ) |
111 | if not platform_utils.isdir(item): | 111 | return (ret, buf.getvalue()) |
112 | outstring.append(''.join([status_header, item])) | 112 | |
113 | continue | 113 | def _FindOrphans(self, dirs, proj_dirs, proj_dirs_parents, outstring): |
114 | if item in proj_dirs: | 114 | """find 'dirs' that are present in 'proj_dirs_parents' but not in 'proj_dirs'""" # noqa: E501 |
115 | continue | 115 | status_header = " --\t" |
116 | if item in proj_dirs_parents: | 116 | for item in dirs: |
117 | self._FindOrphans(glob.glob('%s/.*' % item) + | 117 | if not platform_utils.isdir(item): |
118 | glob.glob('%s/*' % item), | 118 | outstring.append("".join([status_header, item])) |
119 | proj_dirs, proj_dirs_parents, outstring) | 119 | continue |
120 | continue | 120 | if item in proj_dirs: |
121 | outstring.append(''.join([status_header, item, '/'])) | 121 | continue |
122 | 122 | if item in proj_dirs_parents: | |
123 | def Execute(self, opt, args): | 123 | self._FindOrphans( |
124 | all_projects = self.GetProjects(args, all_manifests=not opt.this_manifest_only) | 124 | glob.glob("%s/.*" % item) + glob.glob("%s/*" % item), |
125 | 125 | proj_dirs, | |
126 | def _ProcessResults(_pool, _output, results): | 126 | proj_dirs_parents, |
127 | ret = 0 | 127 | outstring, |
128 | for (state, output) in results: | 128 | ) |
129 | if output: | 129 | continue |
130 | print(output, end='') | 130 | outstring.append("".join([status_header, item, "/"])) |
131 | if state == 'CLEAN': | 131 | |
132 | ret += 1 | 132 | def Execute(self, opt, args): |
133 | return ret | 133 | all_projects = self.GetProjects( |
134 | 134 | args, all_manifests=not opt.this_manifest_only | |
135 | counter = self.ExecuteInParallel( | 135 | ) |
136 | opt.jobs, | 136 | |
137 | functools.partial(self._StatusHelper, opt.quiet, opt.this_manifest_only), | 137 | def _ProcessResults(_pool, _output, results): |
138 | all_projects, | 138 | ret = 0 |
139 | callback=_ProcessResults, | 139 | for state, output in results: |
140 | ordered=True) | 140 | if output: |
141 | 141 | print(output, end="") | |
142 | if not opt.quiet and len(all_projects) == counter: | 142 | if state == "CLEAN": |
143 | print('nothing to commit (working directory clean)') | 143 | ret += 1 |
144 | 144 | return ret | |
145 | if opt.orphans: | 145 | |
146 | proj_dirs = set() | 146 | counter = self.ExecuteInParallel( |
147 | proj_dirs_parents = set() | 147 | opt.jobs, |
148 | for project in self.GetProjects(None, missing_ok=True, all_manifests=not opt.this_manifest_only): | 148 | functools.partial( |
149 | relpath = project.RelPath(local=opt.this_manifest_only) | 149 | self._StatusHelper, opt.quiet, opt.this_manifest_only |
150 | proj_dirs.add(relpath) | 150 | ), |
151 | (head, _tail) = os.path.split(relpath) | 151 | all_projects, |
152 | while head != "": | 152 | callback=_ProcessResults, |
153 | proj_dirs_parents.add(head) | 153 | ordered=True, |
154 | (head, _tail) = os.path.split(head) | 154 | ) |
155 | proj_dirs.add('.repo') | 155 | |
156 | 156 | if not opt.quiet and len(all_projects) == counter: | |
157 | class StatusColoring(Coloring): | 157 | print("nothing to commit (working directory clean)") |
158 | def __init__(self, config): | 158 | |
159 | Coloring.__init__(self, config, 'status') | 159 | if opt.orphans: |
160 | self.project = self.printer('header', attr='bold') | 160 | proj_dirs = set() |
161 | self.untracked = self.printer('untracked', fg='red') | 161 | proj_dirs_parents = set() |
162 | 162 | for project in self.GetProjects( | |
163 | orig_path = os.getcwd() | 163 | None, missing_ok=True, all_manifests=not opt.this_manifest_only |
164 | try: | 164 | ): |
165 | os.chdir(self.manifest.topdir) | 165 | relpath = project.RelPath(local=opt.this_manifest_only) |
166 | 166 | proj_dirs.add(relpath) | |
167 | outstring = [] | 167 | (head, _tail) = os.path.split(relpath) |
168 | self._FindOrphans(glob.glob('.*') + | 168 | while head != "": |
169 | glob.glob('*'), | 169 | proj_dirs_parents.add(head) |
170 | proj_dirs, proj_dirs_parents, outstring) | 170 | (head, _tail) = os.path.split(head) |
171 | 171 | proj_dirs.add(".repo") | |
172 | if outstring: | 172 | |
173 | output = StatusColoring(self.client.globalConfig) | 173 | class StatusColoring(Coloring): |
174 | output.project('Objects not within a project (orphans)') | 174 | def __init__(self, config): |
175 | output.nl() | 175 | Coloring.__init__(self, config, "status") |
176 | for entry in outstring: | 176 | self.project = self.printer("header", attr="bold") |
177 | output.untracked(entry) | 177 | self.untracked = self.printer("untracked", fg="red") |
178 | output.nl() | 178 | |
179 | else: | 179 | orig_path = os.getcwd() |
180 | print('No orphan files or directories') | 180 | try: |
181 | 181 | os.chdir(self.manifest.topdir) | |
182 | finally: | 182 | |
183 | # Restore CWD. | 183 | outstring = [] |
184 | os.chdir(orig_path) | 184 | self._FindOrphans( |
185 | glob.glob(".*") + glob.glob("*"), | ||
186 | proj_dirs, | ||
187 | proj_dirs_parents, | ||
188 | outstring, | ||
189 | ) | ||
190 | |||
191 | if outstring: | ||
192 | output = StatusColoring(self.client.globalConfig) | ||
193 | output.project("Objects not within a project (orphans)") | ||
194 | output.nl() | ||
195 | for entry in outstring: | ||
196 | output.untracked(entry) | ||
197 | output.nl() | ||
198 | else: | ||
199 | print("No orphan files or directories") | ||
200 | |||
201 | finally: | ||
202 | # Restore CWD. | ||
203 | os.chdir(orig_path) | ||