update analytics in generate api docs site to use new UA4 (#136497)
Change the analytics instance that the generated api.flutter.dev and master-api.flutter.dev use.
This commit is contained in:
parent
bb7f0b2326
commit
4dcd1598b7
4
dev/docs/analytics-footer.html
Normal file
4
dev/docs/analytics-footer.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<!-- Google Tag Manager (noscript) -->
|
||||||
|
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-ND4LWWZ"
|
||||||
|
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||||
|
<!-- End Google Tag Manager (noscript) -->
|
7
dev/docs/analytics-header.html
Normal file
7
dev/docs/analytics-header.html
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<!-- Google Tag Manager -->
|
||||||
|
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||||
|
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||||
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||||
|
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f)
|
||||||
|
})(window,document,'script','dataLayer','GTM-ND4LWWZ');</script>
|
||||||
|
<!-- End Google Tag Manager -->
|
@ -1,9 +0,0 @@
|
|||||||
<script>
|
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
|
||||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
|
||||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
|
||||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
|
||||||
|
|
||||||
ga('create', 'UA-67589403-1', 'auto');
|
|
||||||
ga('send', 'pageview');
|
|
||||||
</script>
|
|
@ -518,9 +518,9 @@ class DartdocGenerator {
|
|||||||
final Version version = FlutterInformation.instance.getFlutterVersion();
|
final Version version = FlutterInformation.instance.getFlutterVersion();
|
||||||
|
|
||||||
// Verify which version of snippets and dartdoc we're using.
|
// Verify which version of snippets and dartdoc we're using.
|
||||||
final ProcessResult snippetsResult = Process.runSync(
|
final ProcessResult snippetsResult = processManager.runSync(
|
||||||
FlutterInformation.instance.getFlutterBinaryPath().path,
|
|
||||||
<String>[
|
<String>[
|
||||||
|
FlutterInformation.instance.getFlutterBinaryPath().path,
|
||||||
'pub',
|
'pub',
|
||||||
'global',
|
'global',
|
||||||
'list',
|
'list',
|
||||||
@ -574,13 +574,15 @@ class DartdocGenerator {
|
|||||||
'--header',
|
'--header',
|
||||||
docsRoot.childFile('styles.html').path,
|
docsRoot.childFile('styles.html').path,
|
||||||
'--header',
|
'--header',
|
||||||
docsRoot.childFile('analytics.html').path,
|
docsRoot.childFile('analytics-header.html').path,
|
||||||
'--header',
|
'--header',
|
||||||
docsRoot.childFile('survey.html').path,
|
docsRoot.childFile('survey.html').path,
|
||||||
'--header',
|
'--header',
|
||||||
docsRoot.childFile('snippets.html').path,
|
docsRoot.childFile('snippets.html').path,
|
||||||
'--header',
|
'--header',
|
||||||
docsRoot.childFile('opensearch.html').path,
|
docsRoot.childFile('opensearch.html').path,
|
||||||
|
'--footer',
|
||||||
|
docsRoot.childFile('analytics-footer.html').path,
|
||||||
'--footer-text',
|
'--footer-text',
|
||||||
packageRoot.childFile('footer.html').path,
|
packageRoot.childFile('footer.html').path,
|
||||||
'--allow-warnings-in-packages',
|
'--allow-warnings-in-packages',
|
||||||
@ -643,6 +645,7 @@ class DartdocGenerator {
|
|||||||
arguments: dartdocArgs,
|
arguments: dartdocArgs,
|
||||||
workingDirectory: packageRoot,
|
workingDirectory: packageRoot,
|
||||||
environment: pubEnvironment,
|
environment: pubEnvironment,
|
||||||
|
processManager: processManager,
|
||||||
));
|
));
|
||||||
printStream(
|
printStream(
|
||||||
process.stdout,
|
process.stdout,
|
||||||
@ -669,7 +672,7 @@ class DartdocGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_sanityCheckDocs();
|
_sanityCheckDocs();
|
||||||
checkForUnresolvedDirectives(publishRoot.childDirectory('flutter').path);
|
checkForUnresolvedDirectives(publishRoot.childDirectory('flutter'));
|
||||||
|
|
||||||
_createIndexAndCleanup();
|
_createIndexAndCleanup();
|
||||||
|
|
||||||
@ -690,12 +693,13 @@ class DartdocGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs a sanity check by running a test.
|
/// A subset of all generated doc files for [_sanityCheckDocs].
|
||||||
void _sanityCheckDocs([Platform platform = const LocalPlatform()]) {
|
@visibleForTesting
|
||||||
|
List<File> get canaries {
|
||||||
final Directory flutterDirectory = publishRoot.childDirectory('flutter');
|
final Directory flutterDirectory = publishRoot.childDirectory('flutter');
|
||||||
final Directory widgetsDirectory = flutterDirectory.childDirectory('widgets');
|
final Directory widgetsDirectory = flutterDirectory.childDirectory('widgets');
|
||||||
|
|
||||||
final List<File> canaries = <File>[
|
return <File>[
|
||||||
publishRoot.childDirectory('assets').childFile('overrides.css'),
|
publishRoot.childDirectory('assets').childFile('overrides.css'),
|
||||||
flutterDirectory.childDirectory('dart-io').childFile('File-class.html'),
|
flutterDirectory.childDirectory('dart-io').childFile('File-class.html'),
|
||||||
flutterDirectory.childDirectory('dart-ui').childFile('Canvas-class.html'),
|
flutterDirectory.childDirectory('dart-ui').childFile('Canvas-class.html'),
|
||||||
@ -710,12 +714,19 @@ class DartdocGenerator {
|
|||||||
widgetsDirectory.childFile('Widget-class.html'),
|
widgetsDirectory.childFile('Widget-class.html'),
|
||||||
widgetsDirectory.childFile('Listener-class.html'),
|
widgetsDirectory.childFile('Listener-class.html'),
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs a sanity check by running a test.
|
||||||
|
void _sanityCheckDocs([Platform platform = const LocalPlatform()]) {
|
||||||
for (final File canary in canaries) {
|
for (final File canary in canaries) {
|
||||||
if (!canary.existsSync()) {
|
if (!canary.existsSync()) {
|
||||||
throw Exception('Missing "${canary.path}", which probably means the documentation failed to build correctly.');
|
throw Exception('Missing "${canary.path}", which probably means the documentation failed to build correctly.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Make sure at least one example of each kind includes source code.
|
// Make sure at least one example of each kind includes source code.
|
||||||
|
final Directory widgetsDirectory = publishRoot
|
||||||
|
.childDirectory('flutter')
|
||||||
|
.childDirectory('widgets');
|
||||||
|
|
||||||
// Check a "sample" example, any one will do.
|
// Check a "sample" example, any one will do.
|
||||||
_sanityCheckExample(
|
_sanityCheckExample(
|
||||||
|
@ -4,9 +4,31 @@
|
|||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
import 'package:path/path.dart' as path;
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
/// Scans the dartdoc HTML output in the provided `htmlOutputPath` for
|
/// Makes sure that the path we were given contains some of the expected
|
||||||
|
/// libraries.
|
||||||
|
@visibleForTesting
|
||||||
|
const List<String> dartdocDirectiveCanaryLibraries = <String>[
|
||||||
|
'animation',
|
||||||
|
'cupertino',
|
||||||
|
'material',
|
||||||
|
'widgets',
|
||||||
|
'rendering',
|
||||||
|
'flutter_driver',
|
||||||
|
];
|
||||||
|
|
||||||
|
/// Makes sure that the path we were given contains some of the expected
|
||||||
|
/// HTML files.
|
||||||
|
@visibleForTesting
|
||||||
|
const List<String> dartdocDirectiveCanaryFiles = <String>[
|
||||||
|
'Widget-class.html',
|
||||||
|
'Material-class.html',
|
||||||
|
'Canvas-class.html',
|
||||||
|
];
|
||||||
|
|
||||||
|
/// Scans the dartdoc HTML output in the provided `dartDocDir` for
|
||||||
/// unresolved dartdoc directives (`{@foo x y}`).
|
/// unresolved dartdoc directives (`{@foo x y}`).
|
||||||
///
|
///
|
||||||
/// Dartdoc usually replaces those directives with other content. However,
|
/// Dartdoc usually replaces those directives with other content. However,
|
||||||
@ -22,27 +44,14 @@ import 'package:path/path.dart' as path;
|
|||||||
/// ```
|
/// ```
|
||||||
/// void foo({@required int bar});
|
/// void foo({@required int bar});
|
||||||
/// ```
|
/// ```
|
||||||
void checkForUnresolvedDirectives(String htmlOutputPath) {
|
void checkForUnresolvedDirectives(Directory dartDocDir) {
|
||||||
final Directory dartDocDir = Directory(htmlOutputPath);
|
|
||||||
if (!dartDocDir.existsSync()) {
|
if (!dartDocDir.existsSync()) {
|
||||||
throw Exception('Directory with dartdoc output (${dartDocDir.path}) does not exist.');
|
throw Exception('Directory with dartdoc output (${dartDocDir.path}) does not exist.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Makes sure that the path we were given contains some of the expected
|
// Make a copy since this will be mutated
|
||||||
// libraries and HTML files.
|
final List<String> canaryLibraries = dartdocDirectiveCanaryLibraries.toList();
|
||||||
final List<String> canaryLibraries = <String>[
|
final List<String> canaryFiles = dartdocDirectiveCanaryFiles.toList();
|
||||||
'animation',
|
|
||||||
'cupertino',
|
|
||||||
'material',
|
|
||||||
'widgets',
|
|
||||||
'rendering',
|
|
||||||
'flutter_driver',
|
|
||||||
];
|
|
||||||
final List<String> canaryFiles = <String>[
|
|
||||||
'Widget-class.html',
|
|
||||||
'Material-class.html',
|
|
||||||
'Canvas-class.html',
|
|
||||||
];
|
|
||||||
|
|
||||||
print('Scanning for unresolved dartdoc directives...');
|
print('Scanning for unresolved dartdoc directives...');
|
||||||
|
|
||||||
@ -112,5 +121,5 @@ void main(List<String> args) {
|
|||||||
if (!Directory(args.single).existsSync()) {
|
if (!Directory(args.single).existsSync()) {
|
||||||
throw Exception('The dartdoc HTML output directory ${args.single} does not exist.');
|
throw Exception('The dartdoc HTML output directory ${args.single} does not exist.');
|
||||||
}
|
}
|
||||||
checkForUnresolvedDirectives(args.single);
|
checkForUnresolvedDirectives(Directory(args.single));
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import 'package:test/test.dart';
|
|||||||
|
|
||||||
import '../../../packages/flutter_tools/test/src/fake_process_manager.dart';
|
import '../../../packages/flutter_tools/test/src/fake_process_manager.dart';
|
||||||
import '../create_api_docs.dart' as apidocs;
|
import '../create_api_docs.dart' as apidocs;
|
||||||
|
import '../dartdoc_checker.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('FlutterInformation', () {
|
group('FlutterInformation', () {
|
||||||
@ -223,6 +224,235 @@ void main() {
|
|||||||
expect(info['engineRealm'], equals('realm'));
|
expect(info['engineRealm'], equals('realm'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('DartDocGenerator', () {
|
||||||
|
late apidocs.DartdocGenerator generator;
|
||||||
|
late MemoryFileSystem fs;
|
||||||
|
late FakeProcessManager processManager;
|
||||||
|
late Directory publishRoot;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
fs = MemoryFileSystem.test();
|
||||||
|
publishRoot = fs.directory('/path/to/publish');
|
||||||
|
processManager = FakeProcessManager.empty();
|
||||||
|
generator = apidocs.DartdocGenerator(
|
||||||
|
packageRoot: fs.directory('/path/to/package'),
|
||||||
|
publishRoot: publishRoot,
|
||||||
|
docsRoot: fs.directory('/path/to/docs'),
|
||||||
|
filesystem: fs,
|
||||||
|
processManager: processManager,
|
||||||
|
);
|
||||||
|
final Directory repoRoot = fs.directory('/flutter');
|
||||||
|
repoRoot.childDirectory('packages').createSync(recursive: true);
|
||||||
|
apidocs.FlutterInformation.instance = apidocs.FlutterInformation(
|
||||||
|
filesystem: fs,
|
||||||
|
processManager: processManager,
|
||||||
|
platform: FakePlatform(environment: <String, String>{
|
||||||
|
'FLUTTER_ROOT': repoRoot.path,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('.generateDartDoc() invokes dartdoc with the correct command line arguments', () async {
|
||||||
|
processManager.addCommands(<FakeCommand>[
|
||||||
|
const FakeCommand(command: <String>['/flutter/bin/flutter', 'pub', 'get']),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>['/flutter/bin/flutter', '--version', '--machine'],
|
||||||
|
stdout: testVersionInfo,
|
||||||
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <Pattern>['git', 'status', '-b', '--porcelain'],
|
||||||
|
stdout: '## $branchName',
|
||||||
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>['git', 'rev-parse', 'HEAD'],
|
||||||
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>['/flutter/bin/flutter', 'pub', 'global', 'list'],
|
||||||
|
),
|
||||||
|
FakeCommand(
|
||||||
|
command: <Pattern>[
|
||||||
|
'/flutter/bin/flutter',
|
||||||
|
'pub',
|
||||||
|
'global',
|
||||||
|
'run',
|
||||||
|
'--enable-asserts',
|
||||||
|
'dartdoc',
|
||||||
|
'--output',
|
||||||
|
'/path/to/publish/flutter',
|
||||||
|
'--allow-tools',
|
||||||
|
'--json',
|
||||||
|
'--validate-links',
|
||||||
|
'--link-to-source-excludes',
|
||||||
|
'/flutter/bin/cache',
|
||||||
|
'--link-to-source-root',
|
||||||
|
'/flutter',
|
||||||
|
'--link-to-source-uri-template',
|
||||||
|
'https://github.com/flutter/flutter/blob/master/%f%#L%l%',
|
||||||
|
'--inject-html',
|
||||||
|
'--use-base-href',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/styles.html',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/analytics-header.html',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/survey.html',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/snippets.html',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/opensearch.html',
|
||||||
|
'--footer',
|
||||||
|
'/path/to/docs/analytics-footer.html',
|
||||||
|
'--footer-text',
|
||||||
|
'/path/to/package/footer.html',
|
||||||
|
'--allow-warnings-in-packages',
|
||||||
|
// match package names
|
||||||
|
RegExp(r'^(\w+,)+(\w+)$'),
|
||||||
|
'--exclude-packages',
|
||||||
|
RegExp(r'^(\w+,)+(\w+)$'),
|
||||||
|
'--exclude',
|
||||||
|
// match dart package URIs
|
||||||
|
RegExp(r'^([\w\/:.]+,)+([\w\/:.]+)$'),
|
||||||
|
'--favicon',
|
||||||
|
'/path/to/docs/favicon.ico',
|
||||||
|
'--package-order',
|
||||||
|
'flutter,Dart,${apidocs.kPlatformIntegrationPackageName},flutter_test,flutter_driver',
|
||||||
|
'--auto-include-dependencies',
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// This will throw while sanity checking generated files, which is tested independently
|
||||||
|
await expectLater(
|
||||||
|
() => generator.generateDartdoc(),
|
||||||
|
throwsA(
|
||||||
|
isA<Exception>().having(
|
||||||
|
(Exception e) => e.toString(),
|
||||||
|
'message',
|
||||||
|
contains(RegExp(r'Missing .* which probably means the documentation failed to build correctly.')),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(processManager, hasNoRemainingExpectations);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('sanity checks spot check generated files', () async {
|
||||||
|
processManager.addCommands(<FakeCommand>[
|
||||||
|
const FakeCommand(command: <String>['/flutter/bin/flutter', 'pub', 'get']),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>['/flutter/bin/flutter', '--version', '--machine'],
|
||||||
|
stdout: testVersionInfo,
|
||||||
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <Pattern>['git', 'status', '-b', '--porcelain'],
|
||||||
|
stdout: '## $branchName',
|
||||||
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>['git', 'rev-parse', 'HEAD'],
|
||||||
|
),
|
||||||
|
const FakeCommand(
|
||||||
|
command: <String>['/flutter/bin/flutter', 'pub', 'global', 'list'],
|
||||||
|
),
|
||||||
|
FakeCommand(
|
||||||
|
command: <Pattern>[
|
||||||
|
'/flutter/bin/flutter',
|
||||||
|
'pub',
|
||||||
|
'global',
|
||||||
|
'run',
|
||||||
|
'--enable-asserts',
|
||||||
|
'dartdoc',
|
||||||
|
'--output',
|
||||||
|
'/path/to/publish/flutter',
|
||||||
|
'--allow-tools',
|
||||||
|
'--json',
|
||||||
|
'--validate-links',
|
||||||
|
'--link-to-source-excludes',
|
||||||
|
'/flutter/bin/cache',
|
||||||
|
'--link-to-source-root',
|
||||||
|
'/flutter',
|
||||||
|
'--link-to-source-uri-template',
|
||||||
|
'https://github.com/flutter/flutter/blob/master/%f%#L%l%',
|
||||||
|
'--inject-html',
|
||||||
|
'--use-base-href',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/styles.html',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/analytics-header.html',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/survey.html',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/snippets.html',
|
||||||
|
'--header',
|
||||||
|
'/path/to/docs/opensearch.html',
|
||||||
|
'--footer',
|
||||||
|
'/path/to/docs/analytics-footer.html',
|
||||||
|
'--footer-text',
|
||||||
|
'/path/to/package/footer.html',
|
||||||
|
'--allow-warnings-in-packages',
|
||||||
|
// match package names
|
||||||
|
RegExp(r'^(\w+,)+(\w+)$'),
|
||||||
|
'--exclude-packages',
|
||||||
|
RegExp(r'^(\w+,)+(\w+)$'),
|
||||||
|
'--exclude',
|
||||||
|
// match dart package URIs
|
||||||
|
RegExp(r'^([\w\/:.]+,)+([\w\/:.]+)$'),
|
||||||
|
'--favicon',
|
||||||
|
'/path/to/docs/favicon.ico',
|
||||||
|
'--package-order',
|
||||||
|
'flutter,Dart,${apidocs.kPlatformIntegrationPackageName},flutter_test,flutter_driver',
|
||||||
|
'--auto-include-dependencies',
|
||||||
|
],
|
||||||
|
onRun: () {
|
||||||
|
for (final File canary in generator.canaries) {
|
||||||
|
canary.createSync(recursive: true);
|
||||||
|
}
|
||||||
|
for (final String path in dartdocDirectiveCanaryFiles) {
|
||||||
|
publishRoot.childDirectory('flutter').childFile(path).createSync(recursive: true);
|
||||||
|
}
|
||||||
|
for (final String path in dartdocDirectiveCanaryLibraries) {
|
||||||
|
publishRoot.childDirectory('flutter').childDirectory(path).createSync(recursive: true);
|
||||||
|
}
|
||||||
|
publishRoot.childDirectory('flutter').childFile('index.html').createSync();
|
||||||
|
|
||||||
|
final Directory widgetsDir = publishRoot
|
||||||
|
.childDirectory('flutter')
|
||||||
|
.childDirectory('widgets')
|
||||||
|
..createSync(recursive: true);
|
||||||
|
widgetsDir.childFile('showGeneralDialog.html').writeAsStringSync('''
|
||||||
|
<pre id="longSnippet1">
|
||||||
|
<code class="language-dart">
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
''',
|
||||||
|
);
|
||||||
|
expect(publishRoot.childDirectory('flutter').existsSync(), isTrue);
|
||||||
|
(widgetsDir
|
||||||
|
.childDirectory('ModalRoute')
|
||||||
|
..createSync(recursive: true))
|
||||||
|
.childFile('barrierColor.html')
|
||||||
|
.writeAsStringSync('''
|
||||||
|
<pre id="sample-code">
|
||||||
|
<code class="language-dart">
|
||||||
|
class FooClass {
|
||||||
|
Color get barrierColor => FooColor();
|
||||||
|
}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
''');
|
||||||
|
const String queryParams = 'split=1&run=true&sample_id=widgets.Listener.123&sample_channel=master&channel=master';
|
||||||
|
widgetsDir.childFile('Listener-class.html').writeAsStringSync('''
|
||||||
|
<iframe class="snippet-dartpad" src="https://dartpad.dev/embed-flutter.html?$queryParams">
|
||||||
|
</iframe>
|
||||||
|
''');
|
||||||
|
}
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await generator.generateDartdoc();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const String branchName = 'stable';
|
const String branchName = 'stable';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user