run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
void run() async {
showUsage(argResults!.rest.isEmpty, () => printUsage());
final String url = argResults!.rest[0];
// final Aria2Adapter aria2Adapter = Aria2Adapter();
// final CurlAdapter curlAdapter = CurlAdapter();
// final WgetAdapter wgetAdapter = WgetAdapter();
final DioAdapter dioAdapter = DioAdapter();
late final DloaderAdapter adapter;
adapter = dioAdapter;
// if (aria2Adapter.isAvailable) {
// adapter = aria2Adapter;
// } else if (curlAdapter.isAvailable) {
// adapter = curlAdapter;
// } else if (wgetAdapter.isAvailable) {
// adapter = wgetAdapter;
// } else {
// adapter = dioAdapter;
// }
Logger.info("Using ${adapter.executable.cmd} adapter");
final downloader = Dloader(adapter);
Uri uri = Uri.parse(url);
// if no filename in url, generate one randomly
String fileName;
if (argResults!['name'] != null) {
fileName = argResults!['name'];
} else if (uri.pathSegments.isNotEmpty) {
fileName = uri.pathSegments.last;
} else {
fileName = 'file-${DateTime.now().millisecondsSinceEpoch}';
}
Logger.info("File name: $fileName");
File destination;
if (argResults!["out"] != null) {
destination = File(argResults!["out"]);
fileName = destination.path.split("/").last;
} else {
Directory tempDir = await XPM.temp('downloads');
destination = File(join(tempDir.path, fileName));
}
Logger.info("Destination: ${destination.path}");
final progressBarEnabled = !argResults!["no-progress"];
final ProgressState? progressBar;
if (progressBarEnabled) {
progressBar = Progress.withTheme(
theme: Theme.colorfulTheme,
length: 100,
rightPrompt: (current) => ' ${current.toString().padLeft(3)}%',
leftPrompt: (c) => 'Downloading $fileName ',
).interact();
} else {
progressBar = null;
}
int actualProgress = 0;
int lastProgress = 0;
File file = await downloader.download(
url: url,
destination: destination,
userAgent: argResults!['user-agent'],
disableUserAgent: argResults!['no-user-agent'],
onProgress: (progress) {
actualProgress = int.parse(progress['percentComplete']);
if (progressBarEnabled && actualProgress > 0 && actualProgress > lastProgress) {
progressBar!.increase(actualProgress - lastProgress);
lastProgress = actualProgress;
}
},
);
if (progressBarEnabled) {
progressBar!.done();
}
if (argResults!['md5'] != null ||
argResults!['sha1'] != null ||
argResults!['sha256'] != null ||
argResults!['sha512'] != null ||
argResults!['sha224'] != null ||
argResults!['sha384'] != null ||
argResults!['sha512-224'] != null ||
argResults!['sha512-256'] != null) {
Logger.info("Checking hash...");
String? expectedHash;
Digest? fileHash;
final Uint8List asBytes = await file.readAsBytes();
if (argResults!['sha1'] != null) {
expectedHash = argResults!['sha1'];
fileHash = sha1.convert(asBytes);
} else if (argResults!['sha256'] != null) {
expectedHash = argResults!['sha256'];
fileHash = sha256.convert(asBytes);
} else if (argResults!['sha512'] != null) {
expectedHash = argResults!['sha512'];
fileHash = sha512.convert(asBytes);
} else if (argResults!['md5'] != null) {
expectedHash = argResults!['md5'];
fileHash = md5.convert(asBytes);
} else if (argResults!['sha224'] != null) {
expectedHash = argResults!['sha224'];
fileHash = sha224.convert(asBytes);
} else if (argResults!['sha384'] != null) {
expectedHash = argResults!['sha384'];
fileHash = sha384.convert(asBytes);
} else if (argResults!['sha512-224'] != null) {
expectedHash = argResults!['sha512-224'];
fileHash = sha512224.convert(asBytes);
} else if (argResults!['sha512-256'] != null) {
expectedHash = argResults!['sha512-256'];
fileHash = sha512256.convert(asBytes);
}
if (fileHash != null && fileHash.toString() != expectedHash) {
throw Exception('Hash expected $expectedHash, but got $fileHash');
}
}
if (argResults!['bin'] == true || argResults!['exec'] == true) {
final runner = Run();
if (argResults!['exec'] == true && !Platform.isWindows) {
bool asExec = await runner.asExec(file.path, sudo: await Executable('sudo').exists());
if (asExec) {
Logger.info('Made $file executable');
} else {
throw Exception('Failed to make $file executable');
}
}
if (argResults!['bin'] == true) {
// @FIXME shouldn't $destination be set instead use this logic?
final File? toBin = await moveToBin(file, runner: runner, sudo: await Executable('sudo').exists());
if (toBin != null) {
Logger.info('Installed $file to bin folder: ${toBin.path}');
file = toBin;
} else {
throw Exception('Failed to install $file to bin folder');
}
}
}
print(file.absolute.path);
exit(success);
}