Unverified Commit 5259e1bc authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Add --empty to the flutter create command (#113873)

parent 3c2f500b
......@@ -65,6 +65,12 @@ class CreateCommand extends CreateBase {
'https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html',
valueHelp: 'id',
);
argParser.addFlag(
'empty',
abbr: 'e',
help: 'Specifies creating using an application template with a main.dart that is minimal, '
'including no comments, as a starting point for a new application. Implies "--template=app".',
);
argParser.addOption(
'list-samples',
help: 'Specifies a JSON output file for a listing of Flutter code samples '
......@@ -191,9 +197,17 @@ class CreateCommand extends CreateBase {
return FlutterCommandResult.success();
}
if (argResults!.wasParsed('empty') && argResults!.wasParsed('sample')) {
throwToolExit(
'Only one of --empty or --sample may be specified, not both.',
exitCode: 2,
);
}
validateOutputDirectoryArg();
String? sampleCode;
final String? sampleArgument = stringArg('sample');
final bool emptyArgument = boolArg('empty') ?? false;
if (sampleArgument != null) {
final String? templateArgument = stringArg('template');
if (templateArgument != null && stringToProjectType(templateArgument) != FlutterProjectType.app) {
......@@ -299,6 +313,7 @@ class CreateCommand extends CreateBase {
flutterRoot: flutterRoot,
withPlatformChannelPluginHook: generateMethodChannelsPlugin,
withFfiPluginHook: generateFfiPlugin,
withEmptyMain: emptyArgument,
androidLanguage: stringArgDeprecated('android-language'),
iosLanguage: stringArgDeprecated('ios-language'),
iosDevelopmentTeam: developmentTeam,
......@@ -411,11 +426,15 @@ class CreateCommand extends CreateBase {
);
}
if (sampleCode != null) {
generatedFileCount += _applySample(relativeDir, sampleCode);
_applySample(relativeDir, sampleCode);
}
if (sampleCode != null || emptyArgument) {
generatedFileCount += _removeTestDir(relativeDir);
}
globals.printStatus('Wrote $generatedFileCount files.');
globals.printStatus('\nAll done!');
final String application = sampleCode != null ? 'sample application' : 'application';
final String application =
'${emptyArgument ? 'empty' : ''}${sampleCode != null ? 'sample' : ''} application';
if (generatePackage) {
final String relativeMainPath = globals.fs.path.normalize(globals.fs.path.join(
relativeDirPath,
......@@ -657,10 +676,13 @@ Your $application code is in $relativeAppMain.
// documentation website in sampleCode. Returns the difference in the number
// of files after applying the sample, since it also deletes the application's
// test directory (since the template's test doesn't apply to the sample).
int _applySample(Directory directory, String sampleCode) {
void _applySample(Directory directory, String sampleCode) {
final File mainDartFile = directory.childDirectory('lib').childFile('main.dart');
mainDartFile.createSync(recursive: true);
mainDartFile.writeAsStringSync(sampleCode);
}
int _removeTestDir(Directory directory) {
final Directory testDir = directory.childDirectory('test');
final List<FileSystemEntity> files = testDir.listSync(recursive: true);
testDir.deleteSync(recursive: true);
......
......@@ -354,6 +354,7 @@ abstract class CreateBase extends FlutterCommand {
String? gradleVersion,
bool withPlatformChannelPluginHook = false,
bool withFfiPluginHook = false,
bool withEmptyMain = false,
bool ios = false,
bool android = false,
bool web = false,
......@@ -409,6 +410,7 @@ abstract class CreateBase extends FlutterCommand {
'withFfiPluginHook': withFfiPluginHook,
'withPlatformChannelPluginHook': withPlatformChannelPluginHook,
'withPluginHook': withFfiPluginHook || withPlatformChannelPluginHook,
'withEmptyMain': withEmptyMain,
'androidLanguage': androidLanguage,
'iosLanguage': iosLanguage,
'hasIosDevelopmentTeam': iosDevelopmentTeam != null && iosDevelopmentTeam.isNotEmpty,
......
# {{projectName}}
{{description}}
{{^withEmptyMain}}
## Getting Started
......@@ -14,3 +15,4 @@ A few resources to get you started if this is your first Flutter project:
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
{{/withEmptyMain}}
import 'package:flutter/material.dart';
{{#withEmptyMain}}
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text('Hello World!'),
),
),
);
}
}
{{/withEmptyMain}}
{{^withEmptyMain}}
{{#withPlatformChannelPluginHook}}
import 'dart:async';
......@@ -248,3 +270,4 @@ class _MyAppState extends State<MyApp> {
}
}
{{/withFfiPluginHook}}
{{/withEmptyMain}}
name: {{projectName}}
description: {{description}}
{{#withEmptyMain}}
publish_to: 'none'
version: 0.1.0
environment:
sdk: {{dartSdkVersionBounds}}
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
{{/withEmptyMain}}
{{^withEmptyMain}}
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
......@@ -100,3 +119,4 @@ flutter:
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
{{/withEmptyMain}}
{{^withEmptyMain}}
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
......@@ -7,7 +8,9 @@
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
{{/withEmptyMain}}
include: package:flutter_lints/flutter.yaml
{{^withEmptyMain}}
linter:
# The lint rules applied to this project can be customized in the
......@@ -27,3 +30,4 @@ linter:
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
{{/withEmptyMain}}
......@@ -1944,6 +1944,28 @@ void main() {
},
);
testUsingContext('can create an empty application project', () async {
await _createAndAnalyzeProject(
projectDir,
<String>['--no-pub', '--empty'],
<String>[
'lib/main.dart',
'flutter_project.iml',
'android/app/src/main/AndroidManifest.xml',
'ios/Flutter/AppFrameworkInfo.plist',
],
unexpectedPaths: <String>['test'],
);
expect(projectDir.childDirectory('lib').childFile('main.dart').readAsStringSync(),
contains("Text('Hello World!')"));
expect(projectDir.childDirectory('lib').childFile('main.dart').readAsStringSync(),
isNot(contains('int _counter')));
expect(projectDir.childFile('analysis_options.yaml').readAsStringSync(),
isNot(contains('#')));
expect(projectDir.childFile('README.md').readAsStringSync(),
isNot(contains('Getting Started')));
});
testUsingContext('can create a sample-based project', () async {
await _createAndAnalyzeProject(
projectDir,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment