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

Commit ac3167f

Browse files
[flutter_plugin_tools] Adds update-excerpts command (#5339)
1 parent d8f6ddb commit ac3167f

19 files changed

+713
-26
lines changed

.cirrus.yml

+4
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ task:
155155
analyze_script:
156156
- ./script/tool_runner.sh analyze --skip-if-not-supporting-flutter-version="$CHANNEL" --custom-analysis=script/configs/custom_analysis.yaml
157157
- echo "If this test fails, the minumum Flutter version should be updated"
158+
- name: readme_excerpts
159+
env:
160+
CIRRUS_CLONE_SUBMODULES: true
161+
script: ./script/tool_runner.sh update-excerpts --fail-on-change
158162
### Web tasks ###
159163
- name: web-build_all_plugins
160164
env:

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "site-shared"]
2+
path = site-shared
3+
url = https://github.com/dart-lang/site-shared

packages/camera/camera/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.9.4+21
2+
3+
* Fixes README code samples.
4+
15
## 0.9.4+20
26

37
* Fixes an issue with the orientation of videos recorded in landscape on Android.

packages/camera/camera/README.md

+22-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Camera Plugin
22

3+
<?code-excerpt path-base="excerpts/packages/camera_example"?>
4+
35
[![pub package](https://img.shields.io/pub/v/camera.svg)](https://pub.dev/packages/camera)
46

57
A Flutter plugin for iOS, Android and Web allowing access to the device cameras.
@@ -59,33 +61,35 @@ For web integration details, see the
5961

6062
As of version [0.5.0](https://github.com/flutter/plugins/blob/master/packages/camera/CHANGELOG.md#050) of the camera plugin, lifecycle changes are no longer handled by the plugin. This means developers are now responsible to control camera resources when the lifecycle state is updated. Failure to do so might lead to unexpected behavior (for example as described in issue [#39109](https://github.com/flutter/flutter/issues/39109)). Handling lifecycle changes can be done by overriding the `didChangeAppLifecycleState` method like so:
6163

64+
<?code-excerpt "main.dart (AppLifecycle)"?>
6265
```dart
63-
@override
64-
void didChangeAppLifecycleState(AppLifecycleState state) {
65-
// App state changed before we got the chance to initialize.
66-
if (controller == null || !controller.value.isInitialized) {
67-
return;
68-
}
69-
if (state == AppLifecycleState.inactive) {
70-
controller?.dispose();
71-
} else if (state == AppLifecycleState.resumed) {
72-
if (controller != null) {
73-
onNewCameraSelected(controller.description);
74-
}
75-
}
66+
@override
67+
void didChangeAppLifecycleState(AppLifecycleState state) {
68+
final CameraController? cameraController = controller;
69+
70+
// App state changed before we got the chance to initialize.
71+
if (cameraController == null || !cameraController.value.isInitialized) {
72+
return;
7673
}
74+
75+
if (state == AppLifecycleState.inactive) {
76+
cameraController.dispose();
77+
} else if (state == AppLifecycleState.resumed) {
78+
onNewCameraSelected(cameraController.description);
79+
}
80+
}
7781
```
7882

7983
### Example
8084

8185
Here is a small example flutter app displaying a full screen camera preview.
8286

87+
<?code-excerpt "readme_full_example.dart (FullAppExample)"?>
8388
```dart
84-
import 'dart:async';
85-
import 'package:flutter/material.dart';
8689
import 'package:camera/camera.dart';
90+
import 'package:flutter/material.dart';
8791
88-
List<CameraDescription> cameras;
92+
late List<CameraDescription> cameras;
8993
9094
Future<void> main() async {
9195
WidgetsFlutterBinding.ensureInitialized();
@@ -100,7 +104,7 @@ class CameraApp extends StatefulWidget {
100104
}
101105
102106
class _CameraAppState extends State<CameraApp> {
103-
CameraController controller;
107+
late CameraController controller;
104108
105109
@override
106110
void initState() {
@@ -116,7 +120,7 @@ class _CameraAppState extends State<CameraApp> {
116120
117121
@override
118122
void dispose() {
119-
controller?.dispose();
123+
controller.dispose();
120124
super.dispose();
121125
}
122126
@@ -130,7 +134,6 @@ class _CameraAppState extends State<CameraApp> {
130134
);
131135
}
132136
}
133-
134137
```
135138

136139
For a more elaborate usage example see [here](https://github.com/flutter/plugins/tree/main/packages/camera/camera/example).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
targets:
2+
$default:
3+
sources:
4+
include:
5+
- lib/**
6+
# Some default includes that aren't really used here but will prevent
7+
# false-negative warnings:
8+
- $package$
9+
- lib/$lib$
10+
exclude:
11+
- '**/.*/**'
12+
- '**/build/**'
13+
builders:
14+
code_excerpter|code_excerpter:
15+
enabled: true

packages/camera/camera/example/lib/main.dart

+2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
106106
super.dispose();
107107
}
108108

109+
// #docregion AppLifecycle
109110
@override
110111
void didChangeAppLifecycleState(AppLifecycleState state) {
111112
final CameraController? cameraController = controller;
@@ -121,6 +122,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
121122
onNewCameraSelected(cameraController.description);
122123
}
123124
}
125+
// #enddocregion AppLifecycle
124126

125127
@override
126128
Widget build(BuildContext context) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// ignore_for_file: public_member_api_docs
6+
7+
// #docregion FullAppExample
8+
import 'package:camera/camera.dart';
9+
import 'package:flutter/material.dart';
10+
11+
late List<CameraDescription> cameras;
12+
13+
Future<void> main() async {
14+
WidgetsFlutterBinding.ensureInitialized();
15+
16+
cameras = await availableCameras();
17+
runApp(CameraApp());
18+
}
19+
20+
class CameraApp extends StatefulWidget {
21+
@override
22+
_CameraAppState createState() => _CameraAppState();
23+
}
24+
25+
class _CameraAppState extends State<CameraApp> {
26+
late CameraController controller;
27+
28+
@override
29+
void initState() {
30+
super.initState();
31+
controller = CameraController(cameras[0], ResolutionPreset.max);
32+
controller.initialize().then((_) {
33+
if (!mounted) {
34+
return;
35+
}
36+
setState(() {});
37+
});
38+
}
39+
40+
@override
41+
void dispose() {
42+
controller.dispose();
43+
super.dispose();
44+
}
45+
46+
@override
47+
Widget build(BuildContext context) {
48+
if (!controller.value.isInitialized) {
49+
return Container();
50+
}
51+
return MaterialApp(
52+
home: CameraPreview(controller),
53+
);
54+
}
55+
}
56+
// #enddocregion FullAppExample

packages/camera/camera/example/pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ dependencies:
2020
video_player: ^2.1.4
2121

2222
dev_dependencies:
23+
build_runner: ^2.1.10
2324
flutter_driver:
2425
sdk: flutter
2526
flutter_test:

packages/camera/camera/pubspec.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing
44
Dart.
55
repository: https://github.com/flutter/plugins/tree/main/packages/camera/camera
66
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
7-
version: 0.9.4+20
7+
version: 0.9.4+21
88

99
environment:
1010
sdk: ">=2.14.0 <3.0.0"

script/tool/CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
## NEXT
1+
## 0.8.3
22

3+
- Adds a new `update-excerpts` command to maintain README files using the
4+
`code-excerpter` package from flutter/site-shared.
5+
- `license-check` now ignores submodules.
36
- Allows `make-deps-path-based` to skip packages it has alredy rewritten, so
47
that running multiple times won't fail after the first time.
58

script/tool/README.md

+11
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,17 @@ dart run ./script/tool/bin/flutter_plugin_tools.dart native-test --ios --android
107107
dart run ./script/tool/bin/flutter_plugin_tools.dart native-test --macos --packages plugin_name
108108
```
109109

110+
### Update README.md from Example Sources
111+
112+
`update-excerpts` requires sources that are in a submodule. If you didn't clone
113+
with submodules, you will need to `git submodule update --init --recursive`
114+
before running this command.
115+
116+
```sh
117+
cd <repository root>
118+
dart run ./script/tool/bin/flutter_plugin_tools.dart update-excerpts --packages plugin_name
119+
```
120+
110121
### Publish a Release
111122

112123
**Releases are automated for `flutter/plugins` and `flutter/packages`.**

script/tool/lib/src/license_check_command.dart

+31-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
// found in the LICENSE file.
44

55
import 'package:file/file.dart';
6+
import 'package:git/git.dart';
67
import 'package:path/path.dart' as p;
8+
import 'package:platform/platform.dart';
79

810
import 'common/core.dart';
911
import 'common/plugin_command.dart';
@@ -105,7 +107,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105107
/// Validates that code files have copyright and license blocks.
106108
class LicenseCheckCommand extends PluginCommand {
107109
/// Creates a new license check command for [packagesDir].
108-
LicenseCheckCommand(Directory packagesDir) : super(packagesDir);
110+
LicenseCheckCommand(Directory packagesDir,
111+
{Platform platform = const LocalPlatform(), GitDir? gitDir})
112+
: super(packagesDir, platform: platform, gitDir: gitDir);
109113

110114
@override
111115
final String name = 'license-check';
@@ -116,7 +120,14 @@ class LicenseCheckCommand extends PluginCommand {
116120

117121
@override
118122
Future<void> run() async {
119-
final Iterable<File> allFiles = await _getAllFiles();
123+
// Create a set of absolute paths to submodule directories, with trailing
124+
// separator, to do prefix matching with to test directory inclusion.
125+
final Iterable<String> submodulePaths = (await _getSubmoduleDirectories())
126+
.map(
127+
(Directory dir) => '${dir.absolute.path}${platform.pathSeparator}');
128+
129+
final Iterable<File> allFiles = (await _getAllFiles()).where(
130+
(File file) => !submodulePaths.any(file.absolute.path.startsWith));
120131

121132
final Iterable<File> codeFiles = allFiles.where((File file) =>
122133
_codeFileExtensions.contains(p.extension(file.path)) &&
@@ -275,6 +286,24 @@ class LicenseCheckCommand extends PluginCommand {
275286
.where((FileSystemEntity entity) => entity is File)
276287
.map((FileSystemEntity file) => file as File)
277288
.toList();
289+
290+
// Returns the directories containing mapped submodules, if any.
291+
Future<Iterable<Directory>> _getSubmoduleDirectories() async {
292+
final List<Directory> submodulePaths = <Directory>[];
293+
final Directory repoRoot =
294+
packagesDir.fileSystem.directory((await gitDir).path);
295+
final File submoduleSpec = repoRoot.childFile('.gitmodules');
296+
if (submoduleSpec.existsSync()) {
297+
final RegExp pathLine = RegExp(r'path\s*=\s*(.*)');
298+
for (final String line in submoduleSpec.readAsLinesSync()) {
299+
final RegExpMatch? match = pathLine.firstMatch(line);
300+
if (match != null) {
301+
submodulePaths.add(repoRoot.childDirectory(match.group(1)!.trim()));
302+
}
303+
}
304+
}
305+
return submodulePaths;
306+
}
278307
}
279308

280309
enum _LicenseFailureType { incorrectFirstParty, unknownThirdParty }

script/tool/lib/src/main.dart

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import 'publish_plugin_command.dart';
2828
import 'pubspec_check_command.dart';
2929
import 'readme_check_command.dart';
3030
import 'test_command.dart';
31+
import 'update_excerpts_command.dart';
3132
import 'version_check_command.dart';
3233
import 'xcode_analyze_command.dart';
3334

@@ -68,6 +69,7 @@ void main(List<String> args) {
6869
..addCommand(PubspecCheckCommand(packagesDir))
6970
..addCommand(ReadmeCheckCommand(packagesDir))
7071
..addCommand(TestCommand(packagesDir))
72+
..addCommand(UpdateExcerptsCommand(packagesDir))
7173
..addCommand(VersionCheckCommand(packagesDir))
7274
..addCommand(XcodeAnalyzeCommand(packagesDir));
7375

0 commit comments

Comments
 (0)