Skip to content

Commit bf3d4c8

Browse files
authored
Add --no-parent-folder flag (#9)
1 parent d91c37e commit bf3d4c8

File tree

2 files changed

+60
-4
lines changed

2 files changed

+60
-4
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ API access is available only to users with active subscriptions. Visit https://a
1212

1313
## Usage
1414

15-
`flutterflow export-code --project <project id> --dest <output folder> --[no-]include-assets --token <token> --[no-]fix`
15+
`flutterflow export-code --project <project id> --dest <output folder> --[no-]include-assets --token <token> --[no-]fix --[no]-parent-folder`
1616

1717
Alternatively, instead of passing `--token` you can set `FLUTTERFLOW_API_TOKEN` environment variable.
1818

@@ -26,6 +26,7 @@ Alternatively, instead of passing `--token` you can set `FLUTTERFLOW_API_TOKEN`
2626
| `--[no-]include-assets` | None | [Optional] Whether to include media assets. Defaults to `false` |
2727
| `--branch-name` | `-b` | [Optional] Which branch to download. Defaults to `main` |
2828
| `--[no-]fix` | None | [Optional] Whether to run `dart fix` on the downloaded code. Defaults to `false`. |
29+
| `--[no-]parent-folder` | None | [Optional] Whether to download code into a project-named sub-folder. If true, downloads all project files directly to the specified directory. Defaults to `true`. |
2930

3031
## Issues
3132

bin/flutterflow_cli.dart

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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>.\nSetting 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+
145188
Future<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({
215265
Future _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

Comments
 (0)