@@ -28,6 +28,7 @@ void main(List<String> args) async {
2828 destinationPath: parsedArguments.command! ['dest' ],
2929 includeAssets: parsedArguments.command! ['include-assets' ],
3030 branchName: parsedArguments.command! ['branch-name' ],
31+ unzipToParentFolder: parsedArguments.command! ['parent-folder' ],
3132 fix: parsedArguments.command! ['fix' ],
3233 );
3334}
@@ -53,6 +54,15 @@ ArgResults _parseArgs(List<String> args) {
5354 negatable: true ,
5455 help: 'Run "dart fix" on the downloaded code.' ,
5556 defaultsTo: false ,
57+ )
58+ ..addFlag (
59+ 'parent-folder' ,
60+ negatable: true ,
61+ help: 'Download into a sub-folder. By default, project is downloaded \n '
62+ 'into a folder named <project>.\n Setting this flag to false will '
63+ 'download all project code directly into the specified directory, '
64+ 'or the current directory if --dest is not set.' ,
65+ defaultsTo: true ,
5666 );
5767
5868 final parser = ArgParser ()
@@ -101,6 +111,7 @@ Future _exportCode({
101111 required String projectId,
102112 required String destinationPath,
103113 required bool includeAssets,
114+ required bool unzipToParentFolder,
104115 required bool fix,
105116 String ? branchName,
106117}) async {
@@ -118,19 +129,26 @@ Future _exportCode({
118129 // Download actual code
119130 final projectZipBytes = base64Decode (result['project_zip' ]);
120131 final projectFolder = ZipDecoder ().decodeBytes (projectZipBytes);
121- extractArchiveToDisk (projectFolder, destinationPath);
132+
133+ if (unzipToParentFolder) {
134+ extractArchiveToDisk (projectFolder, destinationPath);
135+ } else {
136+ extractArchiveToCurrentDirectory (projectFolder, destinationPath);
137+ }
122138
123139 final postCodeGenerationFutures = < Future > [
124140 if (fix)
125141 _runFix (
126142 destinationPath: destinationPath,
127143 projectFolder: projectFolder,
144+ unzipToParentFolder: unzipToParentFolder,
128145 ),
129146 if (includeAssets)
130147 _downloadAssets (
131148 client: client,
132149 destinationPath: destinationPath,
133150 assetDescriptions: result['assets' ],
151+ unzipToParentFolder: unzipToParentFolder,
134152 ),
135153 ];
136154
@@ -142,6 +160,31 @@ Future _exportCode({
142160 }
143161}
144162
163+ // Extract files to the specified directory without a project-named
164+ // parent folder.
165+ void extractArchiveToCurrentDirectory (
166+ Archive projectFolder,
167+ String destinationPath,
168+ ) {
169+ for (final file in projectFolder.files) {
170+ if (file.isFile) {
171+ final data = file.content as List <int >;
172+ final filename = file.name;
173+
174+ // Remove the `<project>` prefix from paths.
175+ final path = path_util.join (
176+ destinationPath,
177+ path_util.joinAll (
178+ path_util.split (filename).sublist (1 ),
179+ ));
180+
181+ final fileOut = File (path);
182+ fileOut.createSync (recursive: true );
183+ fileOut.writeAsBytesSync (data);
184+ }
185+ }
186+ }
187+
145188Future <dynamic > _callExport ({
146189 required final http.Client client,
147190 required String token,
@@ -192,9 +235,16 @@ Future _downloadAssets({
192235 required final http.Client client,
193236 required String destinationPath,
194237 required List <dynamic > assetDescriptions,
238+ required unzipToParentFolder,
195239}) async {
196240 final futures = assetDescriptions.map ((assetDescription) async {
197- final path = assetDescription['path' ];
241+ String path = assetDescription['path' ];
242+
243+ if (! unzipToParentFolder) {
244+ path = path_util.joinAll (
245+ path_util.split (path).sublist (1 ),
246+ );
247+ }
198248 final url = assetDescription['url' ];
199249 final fileDest = path_util.join (destinationPath, path);
200250 try {
@@ -215,6 +265,7 @@ Future _downloadAssets({
215265Future _runFix ({
216266 required String destinationPath,
217267 required Archive projectFolder,
268+ required unzipToParentFolder,
218269}) async {
219270 try {
220271 if (projectFolder.isEmpty) {
@@ -223,10 +274,14 @@ Future _runFix({
223274 final firstFilePath = projectFolder.files.first.name;
224275 final directory = path_util.split (firstFilePath).first;
225276
277+ final workingDirectory = unzipToParentFolder
278+ ? path_util.join (destinationPath, directory)
279+ : destinationPath;
280+
226281 final pubGetResult = await Process .run (
227282 'flutter' ,
228283 ['pub' , 'get' ],
229- workingDirectory: path_util. join (destinationPath, directory) ,
284+ workingDirectory: workingDirectory ,
230285 runInShell: true ,
231286 stdoutEncoding: utf8,
232287 stderrEncoding: utf8,
0 commit comments