Change default organization name to example.com in project templates (#14116)
This commit is contained in:
parent
0efc06ca45
commit
4353297079
@ -22,6 +22,7 @@ import '../flx.dart' as flx;
|
|||||||
import '../globals.dart';
|
import '../globals.dart';
|
||||||
import '../ios/xcodeproj.dart';
|
import '../ios/xcodeproj.dart';
|
||||||
import '../plugins.dart';
|
import '../plugins.dart';
|
||||||
|
import '../project.dart';
|
||||||
import '../runner/flutter_command.dart';
|
import '../runner/flutter_command.dart';
|
||||||
import '../template.dart';
|
import '../template.dart';
|
||||||
import '../version.dart';
|
import '../version.dart';
|
||||||
@ -65,7 +66,7 @@ class CreateCommand extends FlutterCommand {
|
|||||||
);
|
);
|
||||||
argParser.addOption(
|
argParser.addOption(
|
||||||
'org',
|
'org',
|
||||||
defaultsTo: 'com.yourcompany',
|
defaultsTo: 'com.example',
|
||||||
help: 'The organization responsible for your new Flutter project, in reverse domain name notation.\n'
|
help: 'The organization responsible for your new Flutter project, in reverse domain name notation.\n'
|
||||||
'This string is used in Java package names and as prefix in the iOS bundle identifier.'
|
'This string is used in Java package names and as prefix in the iOS bundle identifier.'
|
||||||
);
|
);
|
||||||
@ -135,7 +136,18 @@ class CreateCommand extends FlutterCommand {
|
|||||||
// TODO(goderbauer): Work-around for: https://github.com/dart-lang/path/issues/24
|
// TODO(goderbauer): Work-around for: https://github.com/dart-lang/path/issues/24
|
||||||
if (fs.path.basename(dirPath) == '.')
|
if (fs.path.basename(dirPath) == '.')
|
||||||
dirPath = fs.path.dirname(dirPath);
|
dirPath = fs.path.dirname(dirPath);
|
||||||
final String organization = argResults['org'];
|
String organization = argResults['org'];
|
||||||
|
if (!argResults.wasParsed('org')) {
|
||||||
|
final Set<String> existingOrganizations = await new FlutterProject(projectDir).organizationNames();
|
||||||
|
if (existingOrganizations.length == 1) {
|
||||||
|
organization = existingOrganizations.first;
|
||||||
|
} else if (1 < existingOrganizations.length) {
|
||||||
|
throwToolExit(
|
||||||
|
'Ambiguous organization in existing files: $existingOrganizations.\n'
|
||||||
|
'The --org command line argument must be specified to recreate project.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
final String projectName = fs.path.basename(dirPath);
|
final String projectName = fs.path.basename(dirPath);
|
||||||
|
|
||||||
String error =_validateProjectDir(dirPath, flutterRoot: flutterRoot);
|
String error =_validateProjectDir(dirPath, flutterRoot: flutterRoot);
|
||||||
|
@ -393,10 +393,10 @@ Future<Null> diagnoseXcodeBuildFailure(
|
|||||||
}
|
}
|
||||||
if (result.xcodeBuildExecution != null &&
|
if (result.xcodeBuildExecution != null &&
|
||||||
result.xcodeBuildExecution.buildForPhysicalDevice &&
|
result.xcodeBuildExecution.buildForPhysicalDevice &&
|
||||||
app.id?.contains('com.yourcompany') ?? false) {
|
app.id?.contains('com.example') ?? false) {
|
||||||
printError('');
|
printError('');
|
||||||
printError('It appears that your application still contains the default signing identifier.');
|
printError('It appears that your application still contains the default signing identifier.');
|
||||||
printError("Try replacing 'com.yourcompany' with your signing id in Xcode:");
|
printError("Try replacing 'com.example' with your signing id in Xcode:");
|
||||||
printError(' open ios/Runner.xcworkspace');
|
printError(' open ios/Runner.xcworkspace');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
96
packages/flutter_tools/lib/src/project.dart
Normal file
96
packages/flutter_tools/lib/src/project.dart
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'base/file_system.dart';
|
||||||
|
|
||||||
|
/// Represents the contents of a Flutter project at the specified [directory].
|
||||||
|
class FlutterProject {
|
||||||
|
FlutterProject(this.directory);
|
||||||
|
|
||||||
|
/// The location of this project.
|
||||||
|
final Directory directory;
|
||||||
|
|
||||||
|
/// Asynchronously returns the organization names found in this project as
|
||||||
|
/// part of iOS product bundle identifier, Android application ID, or
|
||||||
|
/// Gradle group ID.
|
||||||
|
Future<Set<String>> organizationNames() async {
|
||||||
|
final List<String> candidates = await Future.wait(<Future<String>>[
|
||||||
|
ios.productBundleIdentifier(),
|
||||||
|
android.applicationId(),
|
||||||
|
android.group(),
|
||||||
|
example.android.applicationId(),
|
||||||
|
example.ios.productBundleIdentifier(),
|
||||||
|
]);
|
||||||
|
return new Set<String>.from(
|
||||||
|
candidates.map(_organizationNameFromPackageName)
|
||||||
|
.where((String name) => name != null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
String _organizationNameFromPackageName(String packageName) {
|
||||||
|
if (packageName != null && 0 <= packageName.lastIndexOf('.'))
|
||||||
|
return packageName.substring(0, packageName.lastIndexOf('.'));
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The iOS sub project of this project.
|
||||||
|
IosProject get ios => new IosProject(directory.childDirectory('ios'));
|
||||||
|
|
||||||
|
/// The Android sub project of this project.
|
||||||
|
AndroidProject get android => new AndroidProject(directory.childDirectory('android'));
|
||||||
|
|
||||||
|
/// The example sub project of this (plugin) project.
|
||||||
|
FlutterProject get example => new FlutterProject(directory.childDirectory('example'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the contents of the ios/ folder of a Flutter project.
|
||||||
|
class IosProject {
|
||||||
|
static final RegExp _productBundleIdPattern = new RegExp(r'^\s*PRODUCT_BUNDLE_IDENTIFIER\s*=\s*(.*);\s*$');
|
||||||
|
IosProject(this.directory);
|
||||||
|
|
||||||
|
final Directory directory;
|
||||||
|
|
||||||
|
Future<String> productBundleIdentifier() {
|
||||||
|
final File projectFile = directory.childDirectory('Runner.xcodeproj').childFile('project.pbxproj');
|
||||||
|
return _firstMatchInFile(projectFile, _productBundleIdPattern).then((Match match) => match?.group(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the contents of the android/ folder of a Flutter project.
|
||||||
|
class AndroidProject {
|
||||||
|
static final RegExp _applicationIdPattern = new RegExp('^\\s*applicationId\\s+[\'\"](.*)[\'\"]\\s*\$');
|
||||||
|
static final RegExp _groupPattern = new RegExp('^\\s*group\\s+[\'\"](.*)[\'\"]\\s*\$');
|
||||||
|
|
||||||
|
AndroidProject(this.directory);
|
||||||
|
|
||||||
|
final Directory directory;
|
||||||
|
|
||||||
|
Future<String> applicationId() {
|
||||||
|
final File gradleFile = directory.childDirectory('app').childFile('build.gradle');
|
||||||
|
return _firstMatchInFile(gradleFile, _applicationIdPattern).then((Match match) => match?.group(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> group() {
|
||||||
|
final File gradleFile = directory.childFile('build.gradle');
|
||||||
|
return _firstMatchInFile(gradleFile, _groupPattern).then((Match match) => match?.group(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Asynchronously returns the first line-based match for [regExp] in [file].
|
||||||
|
///
|
||||||
|
/// Assumes UTF8 encoding.
|
||||||
|
Future<Match> _firstMatchInFile(File file, RegExp regExp) async {
|
||||||
|
if (!await file.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return file
|
||||||
|
.openRead()
|
||||||
|
.transform(UTF8.decoder)
|
||||||
|
.transform(const LineSplitter())
|
||||||
|
.map(regExp.firstMatch)
|
||||||
|
.firstWhere((Match match) => match != null, defaultValue: () => null);
|
||||||
|
}
|
@ -62,7 +62,7 @@ final Map<String, String> _swiftBuildSettings = <String, String>{
|
|||||||
'CLANG_ENABLE_MODULES': 'YES',
|
'CLANG_ENABLE_MODULES': 'YES',
|
||||||
'ENABLE_BITCODE': 'NO',
|
'ENABLE_BITCODE': 'NO',
|
||||||
'INFOPLIST_FILE': 'Runner/Info.plist',
|
'INFOPLIST_FILE': 'Runner/Info.plist',
|
||||||
'PRODUCT_BUNDLE_IDENTIFIER': 'com.yourcompany.test',
|
'PRODUCT_BUNDLE_IDENTIFIER': 'com.example.test',
|
||||||
'PRODUCT_NAME': 'blah',
|
'PRODUCT_NAME': 'blah',
|
||||||
'SWIFT_OBJC_BRIDGING_HEADER': 'Runner/Runner-Bridging-Header.h',
|
'SWIFT_OBJC_BRIDGING_HEADER': 'Runner/Runner-Bridging-Header.h',
|
||||||
'SWIFT_OPTIMIZATION_LEVEL': '-Onone',
|
'SWIFT_OPTIMIZATION_LEVEL': '-Onone',
|
||||||
|
@ -11,6 +11,7 @@ import 'package:flutter_tools/src/base/io.dart';
|
|||||||
import 'package:flutter_tools/src/cache.dart';
|
import 'package:flutter_tools/src/cache.dart';
|
||||||
import 'package:flutter_tools/src/commands/create.dart';
|
import 'package:flutter_tools/src/commands/create.dart';
|
||||||
import 'package:flutter_tools/src/dart/sdk.dart';
|
import 'package:flutter_tools/src/dart/sdk.dart';
|
||||||
|
import 'package:flutter_tools/src/project.dart';
|
||||||
import 'package:flutter_tools/src/version.dart';
|
import 'package:flutter_tools/src/version.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
import 'package:process/process.dart';
|
import 'package:process/process.dart';
|
||||||
@ -50,7 +51,7 @@ void main() {
|
|||||||
projectDir,
|
projectDir,
|
||||||
<String>[],
|
<String>[],
|
||||||
<String>[
|
<String>[
|
||||||
'android/app/src/main/java/com/yourcompany/flutterproject/MainActivity.java',
|
'android/app/src/main/java/com/example/flutterproject/MainActivity.java',
|
||||||
'ios/Runner/AppDelegate.h',
|
'ios/Runner/AppDelegate.h',
|
||||||
'ios/Runner/AppDelegate.m',
|
'ios/Runner/AppDelegate.m',
|
||||||
'ios/Runner/main.m',
|
'ios/Runner/main.m',
|
||||||
@ -67,13 +68,13 @@ void main() {
|
|||||||
projectDir,
|
projectDir,
|
||||||
<String>['--no-pub', '--android-language', 'kotlin', '-i', 'swift'],
|
<String>['--no-pub', '--android-language', 'kotlin', '-i', 'swift'],
|
||||||
<String>[
|
<String>[
|
||||||
'android/app/src/main/kotlin/com/yourcompany/flutterproject/MainActivity.kt',
|
'android/app/src/main/kotlin/com/example/flutterproject/MainActivity.kt',
|
||||||
'ios/Runner/AppDelegate.swift',
|
'ios/Runner/AppDelegate.swift',
|
||||||
'ios/Runner/Runner-Bridging-Header.h',
|
'ios/Runner/Runner-Bridging-Header.h',
|
||||||
'lib/main.dart',
|
'lib/main.dart',
|
||||||
],
|
],
|
||||||
unexpectedPaths: <String>[
|
unexpectedPaths: <String>[
|
||||||
'android/app/src/main/java/com/yourcompany/flutterproject/MainActivity.java',
|
'android/app/src/main/java/com/example/flutterproject/MainActivity.java',
|
||||||
'ios/Runner/AppDelegate.h',
|
'ios/Runner/AppDelegate.h',
|
||||||
'ios/Runner/AppDelegate.m',
|
'ios/Runner/AppDelegate.m',
|
||||||
'ios/Runner/main.m',
|
'ios/Runner/main.m',
|
||||||
@ -90,15 +91,15 @@ void main() {
|
|||||||
'test/flutter_project_test.dart',
|
'test/flutter_project_test.dart',
|
||||||
],
|
],
|
||||||
unexpectedPaths: <String>[
|
unexpectedPaths: <String>[
|
||||||
'android/app/src/main/java/com/yourcompany/flutterproject/MainActivity.java',
|
'android/app/src/main/java/com/example/flutterproject/MainActivity.java',
|
||||||
'android/src/main/java/com/yourcompany/flutterproject/FlutterProjectPlugin.java',
|
'android/src/main/java/com/example/flutterproject/FlutterProjectPlugin.java',
|
||||||
'ios/Classes/FlutterProjectPlugin.h',
|
'ios/Classes/FlutterProjectPlugin.h',
|
||||||
'ios/Classes/FlutterProjectPlugin.m',
|
'ios/Classes/FlutterProjectPlugin.m',
|
||||||
'ios/Runner/AppDelegate.h',
|
'ios/Runner/AppDelegate.h',
|
||||||
'ios/Runner/AppDelegate.m',
|
'ios/Runner/AppDelegate.m',
|
||||||
'ios/Runner/main.m',
|
'ios/Runner/main.m',
|
||||||
'lib/main.dart',
|
'lib/main.dart',
|
||||||
'example/android/app/src/main/java/com/yourcompany/flutterprojectexample/MainActivity.java',
|
'example/android/app/src/main/java/com/example/flutterprojectexample/MainActivity.java',
|
||||||
'example/ios/Runner/AppDelegate.h',
|
'example/ios/Runner/AppDelegate.h',
|
||||||
'example/ios/Runner/AppDelegate.m',
|
'example/ios/Runner/AppDelegate.m',
|
||||||
'example/ios/Runner/main.m',
|
'example/ios/Runner/main.m',
|
||||||
@ -114,11 +115,11 @@ void main() {
|
|||||||
projectDir,
|
projectDir,
|
||||||
<String>['--template=plugin'],
|
<String>['--template=plugin'],
|
||||||
<String>[
|
<String>[
|
||||||
'android/src/main/java/com/yourcompany/flutterproject/FlutterProjectPlugin.java',
|
'android/src/main/java/com/example/flutterproject/FlutterProjectPlugin.java',
|
||||||
'ios/Classes/FlutterProjectPlugin.h',
|
'ios/Classes/FlutterProjectPlugin.h',
|
||||||
'ios/Classes/FlutterProjectPlugin.m',
|
'ios/Classes/FlutterProjectPlugin.m',
|
||||||
'lib/flutter_project.dart',
|
'lib/flutter_project.dart',
|
||||||
'example/android/app/src/main/java/com/yourcompany/flutterprojectexample/MainActivity.java',
|
'example/android/app/src/main/java/com/example/flutterprojectexample/MainActivity.java',
|
||||||
'example/ios/Runner/AppDelegate.h',
|
'example/ios/Runner/AppDelegate.h',
|
||||||
'example/ios/Runner/AppDelegate.m',
|
'example/ios/Runner/AppDelegate.m',
|
||||||
'example/ios/Runner/main.m',
|
'example/ios/Runner/main.m',
|
||||||
@ -135,19 +136,19 @@ void main() {
|
|||||||
projectDir,
|
projectDir,
|
||||||
<String>['--no-pub', '--template=plugin', '-a', 'kotlin', '--ios-language', 'swift'],
|
<String>['--no-pub', '--template=plugin', '-a', 'kotlin', '--ios-language', 'swift'],
|
||||||
<String>[
|
<String>[
|
||||||
'android/src/main/kotlin/com/yourcompany/flutterproject/FlutterProjectPlugin.kt',
|
'android/src/main/kotlin/com/example/flutterproject/FlutterProjectPlugin.kt',
|
||||||
'ios/Classes/FlutterProjectPlugin.h',
|
'ios/Classes/FlutterProjectPlugin.h',
|
||||||
'ios/Classes/FlutterProjectPlugin.m',
|
'ios/Classes/FlutterProjectPlugin.m',
|
||||||
'ios/Classes/SwiftFlutterProjectPlugin.swift',
|
'ios/Classes/SwiftFlutterProjectPlugin.swift',
|
||||||
'lib/flutter_project.dart',
|
'lib/flutter_project.dart',
|
||||||
'example/android/app/src/main/kotlin/com/yourcompany/flutterprojectexample/MainActivity.kt',
|
'example/android/app/src/main/kotlin/com/example/flutterprojectexample/MainActivity.kt',
|
||||||
'example/ios/Runner/AppDelegate.swift',
|
'example/ios/Runner/AppDelegate.swift',
|
||||||
'example/ios/Runner/Runner-Bridging-Header.h',
|
'example/ios/Runner/Runner-Bridging-Header.h',
|
||||||
'example/lib/main.dart',
|
'example/lib/main.dart',
|
||||||
],
|
],
|
||||||
unexpectedPaths: <String>[
|
unexpectedPaths: <String>[
|
||||||
'android/src/main/java/com/yourcompany/flutterproject/FlutterProjectPlugin.java',
|
'android/src/main/java/com/example/flutterproject/FlutterProjectPlugin.java',
|
||||||
'example/android/app/src/main/java/com/yourcompany/flutterprojectexample/MainActivity.java',
|
'example/android/app/src/main/java/com/example/flutterprojectexample/MainActivity.java',
|
||||||
'example/ios/Runner/AppDelegate.h',
|
'example/ios/Runner/AppDelegate.h',
|
||||||
'example/ios/Runner/AppDelegate.m',
|
'example/ios/Runner/AppDelegate.m',
|
||||||
'example/ios/Runner/main.m',
|
'example/ios/Runner/main.m',
|
||||||
@ -158,17 +159,17 @@ void main() {
|
|||||||
|
|
||||||
testUsingContext('plugin project with custom org', () async {
|
testUsingContext('plugin project with custom org', () async {
|
||||||
return _createProject(
|
return _createProject(
|
||||||
projectDir,
|
projectDir,
|
||||||
<String>['--no-pub', '--template=plugin', '--org', 'com.bar.foo'],
|
<String>['--no-pub', '--template=plugin', '--org', 'com.bar.foo'],
|
||||||
<String>[
|
<String>[
|
||||||
'android/src/main/java/com/bar/foo/flutterproject/FlutterProjectPlugin.java',
|
'android/src/main/java/com/bar/foo/flutterproject/FlutterProjectPlugin.java',
|
||||||
'example/android/app/src/main/java/com/bar/foo/flutterprojectexample/MainActivity.java',
|
'example/android/app/src/main/java/com/bar/foo/flutterprojectexample/MainActivity.java',
|
||||||
],
|
],
|
||||||
unexpectedPaths: <String>[
|
unexpectedPaths: <String>[
|
||||||
'android/src/main/java/com/yourcompany/flutterproject/FlutterProjectPlugin.java',
|
'android/src/main/java/com/example/flutterproject/FlutterProjectPlugin.java',
|
||||||
'example/android/app/src/main/java/com/yourcompany/flutterprojectexample/MainActivity.java',
|
'example/android/app/src/main/java/com/example/flutterprojectexample/MainActivity.java',
|
||||||
],
|
],
|
||||||
plugin: true,
|
plugin: true,
|
||||||
);
|
);
|
||||||
}, timeout: allowForCreateFlutterProject);
|
}, timeout: allowForCreateFlutterProject);
|
||||||
|
|
||||||
@ -252,6 +253,83 @@ void main() {
|
|||||||
await runner.run(<String>['create', '--no-pub', projectDir.path]);
|
await runner.run(<String>['create', '--no-pub', projectDir.path]);
|
||||||
}, timeout: allowForCreateFlutterProject);
|
}, timeout: allowForCreateFlutterProject);
|
||||||
|
|
||||||
|
testUsingContext('can re-gen android/ folder, reusing custom org', () async {
|
||||||
|
await _createProject(
|
||||||
|
projectDir,
|
||||||
|
<String>['--no-pub', '--org', 'com.bar.foo'],
|
||||||
|
<String>[],
|
||||||
|
);
|
||||||
|
projectDir.childDirectory('android').deleteSync(recursive: true);
|
||||||
|
return _createProject(
|
||||||
|
projectDir,
|
||||||
|
<String>['--no-pub'],
|
||||||
|
<String>[
|
||||||
|
'android/app/src/main/java/com/bar/foo/flutterproject/MainActivity.java',
|
||||||
|
],
|
||||||
|
unexpectedPaths: <String>[
|
||||||
|
'android/app/src/main/java/com/example/flutterproject/MainActivity.java',
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}, timeout: allowForCreateFlutterProject);
|
||||||
|
|
||||||
|
testUsingContext('can re-gen ios/ folder, reusing custom org', () async {
|
||||||
|
await _createProject(
|
||||||
|
projectDir,
|
||||||
|
<String>['--no-pub', '--org', 'com.bar.foo'],
|
||||||
|
<String>[],
|
||||||
|
);
|
||||||
|
projectDir.childDirectory('ios').deleteSync(recursive: true);
|
||||||
|
await _createProject(projectDir, <String>['--no-pub'], <String>[]);
|
||||||
|
expect(
|
||||||
|
await new FlutterProject(projectDir).ios.productBundleIdentifier(),
|
||||||
|
'com.bar.foo.flutterProject',
|
||||||
|
);
|
||||||
|
}, timeout: allowForCreateFlutterProject);
|
||||||
|
|
||||||
|
testUsingContext('can re-gen plugin ios/ and example/ folders, reusing custom org', () async {
|
||||||
|
await _createProject(
|
||||||
|
projectDir,
|
||||||
|
<String>['--no-pub', '-t', 'plugin', '--org', 'com.bar.foo'],
|
||||||
|
<String>[],
|
||||||
|
);
|
||||||
|
projectDir.childDirectory('example').deleteSync(recursive: true);
|
||||||
|
projectDir.childDirectory('ios').deleteSync(recursive: true);
|
||||||
|
await _createProject(
|
||||||
|
projectDir,
|
||||||
|
<String>['--no-pub', '-t', 'plugin'],
|
||||||
|
<String>[
|
||||||
|
'example/android/app/src/main/java/com/bar/foo/flutterprojectexample/MainActivity.java',
|
||||||
|
'ios/Classes/FlutterProjectPlugin.h',
|
||||||
|
],
|
||||||
|
unexpectedPaths: <String>[
|
||||||
|
'example/android/app/src/main/java/com/example/flutterprojectexample/MainActivity.java',
|
||||||
|
'android/src/main/java/com/example/flutterproject/FlutterProjectPlugin.java',
|
||||||
|
],
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
await new FlutterProject(projectDir).example.ios.productBundleIdentifier(),
|
||||||
|
'com.bar.foo.flutterProjectExample',
|
||||||
|
);
|
||||||
|
}, timeout: allowForCreateFlutterProject);
|
||||||
|
|
||||||
|
testUsingContext('fails to re-gen without specified org when org is ambiguous', () async {
|
||||||
|
await _createProject(
|
||||||
|
projectDir,
|
||||||
|
<String>['--no-pub', '--org', 'com.bar.foo'],
|
||||||
|
<String>[],
|
||||||
|
);
|
||||||
|
fs.directory(fs.path.join(projectDir.path, 'ios')).deleteSync(recursive: true);
|
||||||
|
await _createProject(
|
||||||
|
projectDir,
|
||||||
|
<String>['--no-pub', '--org', 'com.bar.baz'],
|
||||||
|
<String>[],
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
() => _createProject(projectDir, <String>[], <String>[]),
|
||||||
|
throwsToolExit(message: 'Ambiguous organization'),
|
||||||
|
);
|
||||||
|
}, timeout: allowForCreateFlutterProject);
|
||||||
|
|
||||||
// Verify that we help the user correct an option ordering issue
|
// Verify that we help the user correct an option ordering issue
|
||||||
testUsingContext('produces sensible error message', () async {
|
testUsingContext('produces sensible error message', () async {
|
||||||
Cache.flutterRoot = '../..';
|
Cache.flutterRoot = '../..';
|
||||||
|
@ -282,7 +282,7 @@ Xcode's output:
|
|||||||
=== CLEAN TARGET Runner OF PROJECT Runner WITH CONFIGURATION Release ===
|
=== CLEAN TARGET Runner OF PROJECT Runner WITH CONFIGURATION Release ===
|
||||||
|
|
||||||
Check dependencies
|
Check dependencies
|
||||||
[BCEROR]No profiles for 'com.yourcompany.test' were found: Xcode couldn't find a provisioning profile matching 'com.yourcompany.test'.
|
[BCEROR]No profiles for 'com.example.test' were found: Xcode couldn't find a provisioning profile matching 'com.example.test'.
|
||||||
[BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
[BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
||||||
[BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
[BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
||||||
[BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
[BCEROR]Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
||||||
@ -304,7 +304,7 @@ Xcode's output:
|
|||||||
=== BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Release ===
|
=== BUILD TARGET Runner OF PROJECT Runner WITH CONFIGURATION Release ===
|
||||||
|
|
||||||
Check dependencies
|
Check dependencies
|
||||||
No profiles for 'com.yourcompany.test' were found: Xcode couldn't find a provisioning profile matching 'com.yourcompany.test'.
|
No profiles for 'com.example.test' were found: Xcode couldn't find a provisioning profile matching 'com.example.test'.
|
||||||
Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
||||||
Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
||||||
Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
Code signing is required for product type 'Application' in SDK 'iOS 10.3'
|
||||||
|
149
packages/flutter_tools/test/project_test.dart
Normal file
149
packages/flutter_tools/test/project_test.dart
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
import 'package:flutter_tools/src/project.dart';
|
||||||
|
import 'package:flutter_tools/src/base/file_system.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:file/file.dart';
|
||||||
|
import 'package:file/memory.dart';
|
||||||
|
|
||||||
|
import 'src/context.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('Project', () {
|
||||||
|
testInMemory('knows location', () {
|
||||||
|
final Directory directory = fs.directory('myproject');
|
||||||
|
expect(new FlutterProject(directory).directory, directory);
|
||||||
|
});
|
||||||
|
group('organization names set', () {
|
||||||
|
testInMemory('is empty, if project not created', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
expect(await project.organizationNames(), isEmpty);
|
||||||
|
});
|
||||||
|
testInMemory('is empty, if no platform folders exist', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
project.directory.createSync();
|
||||||
|
expect(await project.organizationNames(), isEmpty);
|
||||||
|
});
|
||||||
|
testInMemory('is populated from iOS bundle identifier', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
addIosWithBundleId(project.directory, 'io.flutter.someProject');
|
||||||
|
expect(await project.organizationNames(), <String>['io.flutter']);
|
||||||
|
});
|
||||||
|
testInMemory('is populated from Android application ID', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
addAndroidWithApplicationId(project.directory, 'io.flutter.someproject');
|
||||||
|
expect(await project.organizationNames(), <String>['io.flutter']);
|
||||||
|
});
|
||||||
|
testInMemory('is populated from iOS bundle identifier in plugin example', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
addIosWithBundleId(project.example.directory, 'io.flutter.someProject');
|
||||||
|
expect(await project.organizationNames(), <String>['io.flutter']);
|
||||||
|
});
|
||||||
|
testInMemory('is populated from Android application ID in plugin example', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
addAndroidWithApplicationId(project.example.directory, 'io.flutter.someproject');
|
||||||
|
expect(await project.organizationNames(), <String>['io.flutter']);
|
||||||
|
});
|
||||||
|
testInMemory('is populated from Android group in plugin', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
addAndroidWithGroup(project.directory, 'io.flutter.someproject');
|
||||||
|
expect(await project.organizationNames(), <String>['io.flutter']);
|
||||||
|
});
|
||||||
|
testInMemory('is singleton, if sources agree', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
addIosWithBundleId(project.directory, 'io.flutter.someProject');
|
||||||
|
addAndroidWithApplicationId(project.directory, 'io.flutter.someproject');
|
||||||
|
expect(await project.organizationNames(), <String>['io.flutter']);
|
||||||
|
});
|
||||||
|
testInMemory('is non-singleton, if sources disagree', () async {
|
||||||
|
final FlutterProject project = someProject();
|
||||||
|
addIosWithBundleId(project.directory, 'io.flutter.someProject');
|
||||||
|
addAndroidWithApplicationId(project.directory, 'io.clutter.someproject');
|
||||||
|
expect(
|
||||||
|
await project.organizationNames(),
|
||||||
|
<String>['io.flutter', 'io.clutter'],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
FlutterProject someProject() =>
|
||||||
|
new FlutterProject(fs.directory('some_project'));
|
||||||
|
|
||||||
|
void testInMemory(String description, Future<Null> testMethod()) {
|
||||||
|
testUsingContext(
|
||||||
|
description,
|
||||||
|
testMethod,
|
||||||
|
overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addIosWithBundleId(Directory directory, String id) {
|
||||||
|
directory
|
||||||
|
.childDirectory('ios')
|
||||||
|
.childDirectory('Runner.xcodeproj')
|
||||||
|
.childFile('project.pbxproj')
|
||||||
|
..createSync(recursive: true)
|
||||||
|
..writeAsStringSync(projectFileWithBundleId(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addAndroidWithApplicationId(Directory directory, String id) {
|
||||||
|
directory
|
||||||
|
.childDirectory('android')
|
||||||
|
.childDirectory('app')
|
||||||
|
.childFile('build.gradle')
|
||||||
|
..createSync(recursive: true)
|
||||||
|
..writeAsStringSync(gradleFileWithApplicationId(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addAndroidWithGroup(Directory directory, String id) {
|
||||||
|
directory.childDirectory('android').childFile('build.gradle')
|
||||||
|
..createSync(recursive: true)
|
||||||
|
..writeAsStringSync(gradleFileWithGroupId(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
String projectFileWithBundleId(String id) {
|
||||||
|
return '''
|
||||||
|
97C147061CF9000F007C117D /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = $id;
|
||||||
|
PRODUCT_NAME = "\$(TARGET_NAME)";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
|
||||||
|
String gradleFileWithApplicationId(String id) {
|
||||||
|
return '''
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
android {
|
||||||
|
compileSdkVersion 27
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId '$id'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
}
|
||||||
|
|
||||||
|
String gradleFileWithGroupId(String id) {
|
||||||
|
return '''
|
||||||
|
group '$id'
|
||||||
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 27
|
||||||
|
}
|
||||||
|
''';
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user