Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 88276cc

Browse files
committed
Adds a python formatter
1 parent 14194cb commit 88276cc

File tree

7 files changed

+159
-10
lines changed

7 files changed

+159
-10
lines changed

.style.yapf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[style]
2+
based_on_style = yapf
3+
# Defined in https://github.com/google/yapf/blob/20d0c8f1774cf3843f4032f3e9ab02338bf98c75/yapf/yapflib/style.py#L326
4+
# Docs and full list of knobs:
5+
# https://github.com/google/yapf#knobs
6+
split_before_first_argument = true
7+
blank_line_before_module_docstring = true
8+
# dedent_closing_brackets is required by coalesce_brackets
9+
dedent_closing_brackets = true
10+
coalesce_brackets = true
11+
each_dict_entry_on_separate_line = false

DEPS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ deps = {
173173
'src/third_party/boringssl':
174174
Var('github_git') + '/dart-lang/boringssl_gen.git' + '@' + Var('dart_boringssl_gen_rev'),
175175

176+
'src/third_party/yapf':
177+
Var('github_git') + '/google/yapf' + '@' + '212c5b5ad8e172d2d914ae454c121c89cccbcb35',
178+
176179
'src/third_party/boringssl/src':
177180
'https://boringssl.googlesource.com/boringssl.git' + '@' + Var('dart_boringssl_rev'),
178181

ci/bin/format.dart

Lines changed: 110 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,24 @@ enum MessageType {
4545

4646
enum FormatCheck {
4747
clang,
48+
gn,
4849
java,
50+
python,
4951
whitespace,
50-
gn,
5152
}
5253

5354
FormatCheck nameToFormatCheck(String name) {
5455
switch (name) {
5556
case 'clang':
5657
return FormatCheck.clang;
58+
case 'gn':
59+
return FormatCheck.gn;
5760
case 'java':
5861
return FormatCheck.java;
62+
case 'python':
63+
return FormatCheck.python;
5964
case 'whitespace':
6065
return FormatCheck.whitespace;
61-
case 'gn':
62-
return FormatCheck.gn;
6366
default:
6467
throw FormattingException('Unknown FormatCheck type $name');
6568
}
@@ -69,12 +72,14 @@ String formatCheckToName(FormatCheck check) {
6972
switch (check) {
7073
case FormatCheck.clang:
7174
return 'C++/ObjC';
75+
case FormatCheck.gn:
76+
return 'GN';
7277
case FormatCheck.java:
7378
return 'Java';
79+
case FormatCheck.python:
80+
return 'Python';
7481
case FormatCheck.whitespace:
7582
return 'Trailing whitespace';
76-
case FormatCheck.gn:
77-
return 'GN';
7883
}
7984
}
8085

@@ -140,6 +145,15 @@ abstract class FormatChecker {
140145
allFiles: allFiles,
141146
messageCallback: messageCallback,
142147
);
148+
case FormatCheck.gn:
149+
return GnFormatChecker(
150+
processManager: processManager,
151+
baseGitRef: baseGitRef,
152+
repoDir: repoDir,
153+
srcDir: srcDir,
154+
allFiles: allFiles,
155+
messageCallback: messageCallback,
156+
);
143157
case FormatCheck.java:
144158
return JavaFormatChecker(
145159
processManager: processManager,
@@ -149,17 +163,17 @@ abstract class FormatChecker {
149163
allFiles: allFiles,
150164
messageCallback: messageCallback,
151165
);
152-
case FormatCheck.whitespace:
153-
return WhitespaceFormatChecker(
166+
case FormatCheck.python:
167+
return PythonFormatChecker(
154168
processManager: processManager,
155169
baseGitRef: baseGitRef,
156170
repoDir: repoDir,
157171
srcDir: srcDir,
158172
allFiles: allFiles,
159173
messageCallback: messageCallback,
160174
);
161-
case FormatCheck.gn:
162-
return GnFormatChecker(
175+
case FormatCheck.whitespace:
176+
return WhitespaceFormatChecker(
163177
processManager: processManager,
164178
baseGitRef: baseGitRef,
165179
repoDir: repoDir,
@@ -665,6 +679,93 @@ class GnFormatChecker extends FormatChecker {
665679
}
666680
}
667681

682+
/// Checks the format of any .py files using the "yapf" command.
683+
class PythonFormatChecker extends FormatChecker {
684+
PythonFormatChecker({
685+
ProcessManager processManager = const LocalProcessManager(),
686+
required String baseGitRef,
687+
required Directory repoDir,
688+
required Directory srcDir,
689+
bool allFiles = false,
690+
MessageCallback? messageCallback,
691+
}) : super(
692+
processManager: processManager,
693+
baseGitRef: baseGitRef,
694+
repoDir: repoDir,
695+
srcDir: srcDir,
696+
allFiles: allFiles,
697+
messageCallback: messageCallback,
698+
) {
699+
yapfBin = File(path.join(
700+
repoDir.absolute.path,
701+
'tools',
702+
'yapf.sh',
703+
));
704+
_yapfStyle = File(path.join(
705+
repoDir.absolute.path,
706+
'.style.yapf',
707+
));
708+
}
709+
710+
late final File yapfBin;
711+
late final File _yapfStyle;
712+
713+
@override
714+
Future<bool> checkFormatting() async {
715+
message('Checking Python formatting...');
716+
return (await _runYapfCheck(fixing: false)) == 0;
717+
}
718+
719+
@override
720+
Future<bool> fixFormatting() async {
721+
message('Fixing Python formatting...');
722+
await _runYapfCheck(fixing: true);
723+
// The yapf script shouldn't fail when fixing errors.
724+
return true;
725+
}
726+
727+
Future<int> _runYapfCheck({required bool fixing}) async {
728+
final List<String> filesToCheck = await getFileList(<String>['*.py']);
729+
730+
final List<String> cmd = <String>[
731+
yapfBin.path,
732+
'--style', _yapfStyle.path,
733+
if (!fixing) '--diff',
734+
if (fixing) '--in-place',
735+
];
736+
final List<WorkerJob> jobs = <WorkerJob>[];
737+
for (final String file in filesToCheck) {
738+
jobs.add(WorkerJob(<String>[...cmd, file]));
739+
}
740+
final ProcessPool yapfPool = ProcessPool(
741+
processRunner: _processRunner,
742+
printReport: namedReport('python format'),
743+
);
744+
final List<WorkerJob> completedJobs = await yapfPool.runToCompletion(jobs);
745+
reportDone();
746+
final List<String> incorrect = <String>[];
747+
for (final WorkerJob job in completedJobs) {
748+
if (job.result.exitCode == 1) {
749+
incorrect.add(' ${job.command.last}\n${job.result.output}');
750+
}
751+
}
752+
if (incorrect.isNotEmpty) {
753+
final bool plural = incorrect.length > 1;
754+
if (fixing) {
755+
message('Fixed ${incorrect.length} python file${plural ? 's' : ''}'
756+
' which ${plural ? 'were' : 'was'} formatted incorrectly.');
757+
} else {
758+
error('Found ${incorrect.length} python file${plural ? 's' : ''}'
759+
' which ${plural ? 'were' : 'was'} formatted incorrectly:');
760+
incorrect.forEach(stderr.writeln);
761+
}
762+
} else {
763+
message('All python files formatted correctly.');
764+
}
765+
return incorrect.length;
766+
}
767+
}
768+
668769
@immutable
669770
class _GrepResult {
670771
const _GrepResult(this.file, [this.hits = const <String>[], this.lineNumbers = const <int>[]]);

ci/licenses_golden/licenses_flutter

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ LIBRARY: txt
1212
ORIGIN: ../../../flutter/LICENSE
1313
TYPE: LicenseType.bsd
1414
FILE: ../../../flutter/.clang-tidy
15+
FILE: ../../../flutter/.style.yapf
1516
FILE: ../../../flutter/DEPS
1617
FILE: ../../../flutter/assets/asset_manager.cc
1718
FILE: ../../../flutter/assets/asset_manager.h

ci/licenses_golden/tool_signature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Signature: 7b0c7d76d9cfc331776ed8d447e52f67
1+
Signature: 4d80570261409484c1813b3fe5282783
22

tools/licenses/lib/main.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,6 +1844,7 @@ class _RepositoryRootThirdPartyDirectory extends _RepositoryGenericThirdPartyDir
18441844
&& entry.name != 'mockito' // only used by tests
18451845
&& entry.name != 'pymock' // presumably only used by tests
18461846
&& entry.name != 'pyyaml' // build-time dependency only
1847+
&& entry.name != 'yapf' // only used for code formatting
18471848
&& entry.name != 'android_embedding_dependencies' // testing framework for android
18481849
&& entry.name != 'yasm' // build-time dependency only
18491850
&& entry.name != 'binutils' // build-time dependency only

tools/yapf.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2013 The Flutter Authors. All rights reserved.
3+
# Use of this source code is governed by a BSD-style license that can be
4+
# found in the LICENSE file.
5+
6+
# Generates objc docs for Flutter iOS libraries.
7+
8+
set -e
9+
10+
# On Mac OS, readlink -f doesn't work, so follow_links traverses the path one
11+
# link at a time, and then cds into the link destination and find out where it
12+
# ends up.
13+
#
14+
# The function is enclosed in a subshell to avoid changing the working directory
15+
# of the caller.
16+
function follow_links() (
17+
cd -P "$(dirname -- "$1")"
18+
file="$PWD/$(basename -- "$1")"
19+
while [[ -h "$file" ]]; do
20+
cd -P "$(dirname -- "$file")"
21+
file="$(readlink -- "$file")"
22+
cd -P "$(dirname -- "$file")"
23+
file="$PWD/$(basename -- "$file")"
24+
done
25+
echo "$file"
26+
)
27+
28+
SCRIPT_DIR=$(follow_links "$(dirname -- "${BASH_SOURCE[0]}")")
29+
SRC_DIR="$(cd "$SCRIPT_DIR/../.."; pwd -P)"
30+
YAPF_DIR="$(cd "$SRC_DIR/third_party/yapf"; pwd -P)"
31+
32+
PYTHONPATH="$YAPF_DIR" python3 "$YAPF_DIR/yapf" "$@"

0 commit comments

Comments
 (0)