Revert "Revert "Use FlutterProject to locate files (#18913)" (#19409)"  (#19456)

With a fix of a path being printed relative instead of absolute.
diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart
index 0c69f18..7c97cf3 100644
--- a/packages/flutter_tools/lib/src/commands/create.dart
+++ b/packages/flutter_tools/lib/src/commands/create.dart
@@ -168,20 +168,19 @@
 
     printStatus('Creating project ${fs.path.relative(dirPath)}...');
     int generatedFileCount = 0;
-    String appPath = dirPath;
+    final FlutterProject project = new FlutterProject.fromPath(dirPath);
     switch (template) {
       case 'app':
-        generatedFileCount += await _generateApp(dirPath, templateContext);
+        generatedFileCount += await _generateApp(project, templateContext);
         break;
       case 'module':
-        generatedFileCount += await _generateModule(dirPath, templateContext);
+        generatedFileCount += await _generateModule(project, templateContext);
         break;
       case 'package':
-        generatedFileCount += await _generatePackage(dirPath, templateContext);
+        generatedFileCount += await _generatePackage(project, templateContext);
         break;
       case 'plugin':
-        appPath = fs.path.join(dirPath, 'example');
-        generatedFileCount += await _generatePlugin(dirPath, appPath, templateContext);
+        generatedFileCount += await _generatePlugin(project, templateContext);
         break;
     }
     printStatus('Wrote $generatedFileCount files.');
@@ -194,7 +193,8 @@
       printStatus('Your module code is in lib/main.dart in the $relativePath directory.');
     } else {
       // Run doctor; tell the user the next steps.
-      final String relativeAppPath = fs.path.relative(appPath);
+      final FlutterProject app = project.hasExampleApp ? project.example : project;
+      final String relativeAppPath = fs.path.relative(app.directory.path);
       final String relativePluginPath = fs.path.relative(dirPath);
       if (doctor.canLaunchAnything) {
         // Let them know a summary of the state of their tooling.
@@ -233,60 +233,59 @@
     }
   }
 
-  Future<int> _generateModule(String path, Map<String, dynamic> templateContext) async {
+  Future<int> _generateModule(FlutterProject project, Map<String, dynamic> templateContext) async {
     int generatedCount = 0;
     final String description = argResults.wasParsed('description')
         ? argResults['description']
         : 'A new flutter module project.';
     templateContext['description'] = description;
-    generatedCount += _renderTemplate(fs.path.join('module', 'common'), path, templateContext);
+    generatedCount += _renderTemplate(fs.path.join('module', 'common'), project.directory, templateContext);
     if (argResults['pub']) {
       await pubGet(
         context: PubContext.create,
-        directory: path,
+        directory: project.directory.path,
         offline: argResults['offline'],
       );
-      final FlutterProject project = new FlutterProject.fromPath(path);
       await project.ensureReadyForPlatformSpecificTooling();
     }
     return generatedCount;
   }
 
-  Future<int> _generatePackage(String dirPath, Map<String, dynamic> templateContext) async {
+  Future<int> _generatePackage(FlutterProject project, Map<String, dynamic> templateContext) async {
     int generatedCount = 0;
     final String description = argResults.wasParsed('description')
        ? argResults['description']
        : 'A new flutter package project.';
     templateContext['description'] = description;
-    generatedCount += _renderTemplate('package', dirPath, templateContext);
+    generatedCount += _renderTemplate('package', project.directory, templateContext);
 
     if (argResults['pub']) {
       await pubGet(
         context: PubContext.createPackage,
-        directory: dirPath,
+        directory: project.directory.path,
         offline: argResults['offline'],
       );
     }
     return generatedCount;
   }
 
-  Future<int> _generatePlugin(String dirPath, String appPath, Map<String, dynamic> templateContext) async {
+  Future<int> _generatePlugin(FlutterProject project, Map<String, dynamic> templateContext) async {
     int generatedCount = 0;
     final String description = argResults.wasParsed('description')
         ? argResults['description']
         : 'A new flutter plugin project.';
     templateContext['description'] = description;
-    generatedCount += _renderTemplate('plugin', dirPath, templateContext);
+    generatedCount += _renderTemplate('plugin', project.directory, templateContext);
 
     if (argResults['pub']) {
       await pubGet(
         context: PubContext.createPlugin,
-        directory: dirPath,
+        directory: project.directory.path,
         offline: argResults['offline'],
       );
     }
     if (android_sdk.androidSdk != null)
-      await gradle.updateLocalProperties(projectPath: dirPath);
+      await gradle.updateLocalProperties(project: project);
 
     final String projectName = templateContext['projectName'];
     final String organization = templateContext['organization'];
@@ -299,27 +298,27 @@
     templateContext['pluginProjectName'] = projectName;
     templateContext['androidPluginIdentifier'] = androidPluginIdentifier;
 
-    generatedCount += await _generateApp(appPath, templateContext);
+    generatedCount += await _generateApp(project.example, templateContext);
     return generatedCount;
   }
 
-  Future<int> _generateApp(String projectPath, Map<String, dynamic> templateContext) async {
+  Future<int> _generateApp(FlutterProject project, Map<String, dynamic> templateContext) async {
     int generatedCount = 0;
-    generatedCount += _renderTemplate('create', projectPath, templateContext);
-    generatedCount += _injectGradleWrapper(projectPath);
+    generatedCount += _renderTemplate('create', project.directory, templateContext);
+    generatedCount += _injectGradleWrapper(project);
 
     if (argResults['with-driver-test']) {
-      final String testPath = fs.path.join(projectPath, 'test_driver');
-      generatedCount += _renderTemplate('driver', testPath, templateContext);
+      final Directory testDirectory = project.directory.childDirectory('test_driver');
+      generatedCount += _renderTemplate('driver', testDirectory, templateContext);
     }
 
     if (argResults['pub']) {
-      await pubGet(context: PubContext.create, directory: projectPath, offline: argResults['offline']);
-      await new FlutterProject.fromPath(projectPath).ensureReadyForPlatformSpecificTooling();
+      await pubGet(context: PubContext.create, directory: project.directory.path, offline: argResults['offline']);
+      await project.ensureReadyForPlatformSpecificTooling();
     }
 
     if (android_sdk.androidSdk != null)
-      await gradle.updateLocalProperties(projectPath: projectPath);
+      await gradle.updateLocalProperties(project: project);
 
     return generatedCount;
   }
@@ -362,16 +361,16 @@
     };
   }
 
-  int _renderTemplate(String templateName, String dirPath, Map<String, dynamic> context) {
+  int _renderTemplate(String templateName, Directory directory, Map<String, dynamic> context) {
     final Template template = new Template.fromName(templateName);
-    return template.render(fs.directory(dirPath), context, overwriteExisting: false);
+    return template.render(directory, context, overwriteExisting: false);
   }
 
-  int _injectGradleWrapper(String projectDir) {
+  int _injectGradleWrapper(FlutterProject project) {
     int filesCreated = 0;
     copyDirectorySync(
       cache.getArtifactDirectory('gradle_wrapper'),
-      fs.directory(fs.path.join(projectDir, 'android')),
+      project.android.directory,
       (File sourceFile, File destinationFile) {
         filesCreated++;
         final String modes = sourceFile.statSync().modeString();