Skip to content

Commit

Permalink
Merge pull request #29 from Snapp-Embedded/release/v0.6.0
Browse files Browse the repository at this point in the history
fix: fix issue with new flutter version and remove interact_cli dep
  • Loading branch information
payam-zahedi authored Jun 11, 2024
2 parents e197387 + 09848a2 commit 7480181
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 98 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@

## 0.6.0 BETA
* add compatibility with flutter 3.22 by @payam-zahedi

## 0.5.0 BETA
* fix conflict version issue on remote and host machine by @payam-zahedi

Expand Down
10 changes: 4 additions & 6 deletions lib/command_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -162,20 +162,18 @@ Stacktrace: $s

if (!updateConfirmed) return;

final spinner = interaction.runSpinner(
inProgressMessage: 'Updating snapp_cli...',
doneMessage: 'Update process completed!',
failedMessage: 'snapp_cli update failed!',
final progress = interaction.progress(
'Updating snapp_cli...',
);

final result = await updateService.update();

if (result.exitCode != 0) {
spinner.failed();
progress.fail('snapp_cli update failed!');
throwToolExit('Something went wrong. \n ${result.stderr}');
}

spinner.done();
progress.complete('Update process completed!');

logger.spaces();

Expand Down
1 change: 0 additions & 1 deletion lib/commands/devices/commands/list_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class ListCommand extends BaseSnappCommand {

logger.info(result!.stdout);
logger.detail(result.stderr);


return result.exitCode;
}
Expand Down
178 changes: 99 additions & 79 deletions lib/service/interaction_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

import 'dart:io';

import 'package:interact_cli/interact_cli.dart';
import 'package:mason_logger/mason_logger.dart';
import 'package:snapp_cli/commands/base_command.dart';
import 'package:snapp_cli/utils/common.dart';
import 'package:flutter_tools/src/custom_devices/custom_devices_config.dart';
import 'package:flutter_tools/src/custom_devices/custom_device_config.dart';
import 'package:snapp_cli/utils/custom_device.dart';
import 'package:tint/tint.dart';

const interaction = InteractionService._();

Expand All @@ -20,71 +19,64 @@ class InteractionService {
bool? defaultValue,
bool waitForNewLine = true,
}) {
return Confirm(
prompt: message ?? '',
defaultValue: defaultValue,
waitForNewLine: waitForNewLine,
).interact();
return logger.loggerInstance.confirm(
message,
defaultValue: defaultValue ?? false,
);
}

Progress progress(String message) => logger.loggerInstance.progress(message);

Spinner spinner({
required String inProgressMessage,
required String doneMessage,
required String failedMessage,
String? doneIcon,
String? failedIcon,
}) {
return Spinner(
icon: doneIcon ?? logger.icons.success.padRight(2).green().bold(),
failedIcon: failedIcon ?? logger.icons.failure.padRight(2).red().bold(),
rightPrompt: (state) => switch (state) {
SpinnerStateType.inProgress => inProgressMessage,
SpinnerStateType.done => doneMessage,
SpinnerStateType.failed => failedMessage,
},
String doneMessage = 'Done!',
String failedMessage = 'Failed!',
}) =>
Spinner(
inProgressMessage: inProgressMessage,
doneMessage: doneMessage,
failedMessage: failedMessage,
);

String input(String? message, {Object? defaultValue}) {
return logger.loggerInstance.prompt(
message,
defaultValue: defaultValue,
);
}

SpinnerState runSpinner({
required String inProgressMessage,
required String doneMessage,
required String failedMessage,
String? doneIcon,
String? failedIcon,
String inputWithValidation(
String? message, {
required String? Function(String) validator,
Object? defaultValue,
}) {
return spinner(
inProgressMessage: inProgressMessage,
doneMessage: doneMessage,
failedMessage: failedMessage,
doneIcon: doneIcon,
failedIcon: failedIcon,
).interact();
while (true) {
final result = input(message, defaultValue: defaultValue);

final validatorError = validator(result);

if (validatorError == null) {
return result;
}

logger.err(validatorError);

logger.spaces();
}
}

String select(
String? message, {
required List<String> options,
}) {
final selection = Select(
prompt: message ?? '',
options: options,
initialIndex: 0,
).interact();

return options[selection];
}
}) =>
logger.loggerInstance.chooseOne(message, choices: options);

int selectIndex(
String? message, {
required List<String> options,
}) {
final selection = Select(
prompt: message ?? '',
options: options,
initialIndex: 0,
).interact();

return selection;
final selected = select(message, options: options);
return options.indexOf(selected);
}

(InternetAddress ip, String username) getDeviceInfoInteractively(
Expand All @@ -101,10 +93,10 @@ class InteractionService {

logger.spaces();

final deviceTypeIndex = Select(
prompt: 'Device Type:',
final deviceTypeIndex = selectIndex(
'Device Type:',
options: deviceOptions,
).interact();
);

logger.spaces();

Expand Down Expand Up @@ -164,10 +156,10 @@ ${errorDescription ?? 'Before you can select a device, you need to add one first
for (var e in customDevicesConfig.devices) '${e.id} : ${e.label}': e
};

final selectedTarget = Select(
prompt: title ?? 'Select a target device',
final selectedTarget = selectIndex(
title ?? 'Select a target device',
options: devices.keys.toList(),
).interact();
);

final deviceKey = devices.keys.elementAt(selectedTarget);

Expand All @@ -187,15 +179,15 @@ ${errorDescription ?? 'Before you can select a device, you need to add one first
logger.spaces();
}

final String deviceIp = Input(
prompt: title ?? 'Device IP-address:',
final String deviceIp = inputWithValidation(
title ?? 'Device IP-address:',
validator: (s) {
if (s.isValidIpAddress) {
return true;
return null;
}
throw ValidationError('Invalid IP-address. Please try again.');
return 'Invalid IP-address. Please try again.';
},
).interact();
);

final ip = InternetAddress(deviceIp);

Expand All @@ -210,9 +202,7 @@ ${errorDescription ?? 'Before you can select a device, you need to add one first
logger.spaces();
}

final String username = Input(
prompt: 'Username:',
).interact();
final String username = input('Username:');

logger.spaces();

Expand All @@ -228,17 +218,17 @@ ${errorDescription ?? 'Before you can select a device, you need to add one first
'Please enter the id you want to device to have. Must contain only alphanumeric or underscore characters. (example: pi)',
);

final id = Input(
prompt: 'Device Id:',
final id = inputWithValidation(
'Device Id:',
validator: (s) {
if (!RegExp(r'^\w+$').hasMatch(s.trim())) {
throw ValidationError('Invalid input. Please try again.');
return 'Invalid input. Please try again.';
} else if (customDevicesConfig.isDuplicatedDeviceId(s.trim())) {
throw ValidationError('Device with this id already exists.');
return 'Device with this id already exists.';
}
return true;
return null;
},
).interact().trim();
).trim();

logger.spaces();

Expand All @@ -250,15 +240,15 @@ ${errorDescription ?? 'Before you can select a device, you need to add one first
description ??
'Please enter the label of the device, which is a slightly more verbose name for the device. (example: Raspberry Pi Model 4B)',
);
final label = Input(
prompt: 'Device label:',
final label = inputWithValidation(
'Device label:',
validator: (s) {
if (s.trim().isNotEmpty) {
return true;
return null;
}
throw ValidationError('Input is empty. Please try again.');
return 'Input is empty. Please try again.';
},
).interact();
);

logger.spaces();

Expand All @@ -273,15 +263,15 @@ ${errorDescription ?? 'Before you can select a device, you need to add one first
(example: /home/pi/sdk/flutter/bin/flutter)''',
);

final manualFlutterPath = Input(
prompt: 'Flutter path on device:',
final manualFlutterPath = inputWithValidation(
'Flutter path on device:',
validator: (s) {
if (s.isValidPath) {
return true;
return null;
}
throw ValidationError('Invalid Path to flutter. Please try again.');
return 'Invalid Path to flutter. Please try again.';
},
).interact();
);

/// check if [manualFlutterPath] is a valid file path
if (!manualFlutterPath.isValidPath) {
Expand All @@ -292,3 +282,33 @@ ${errorDescription ?? 'Before you can select a device, you need to add one first
return manualFlutterPath;
}
}

class Spinner {
Spinner({
required this.inProgressMessage,
this.doneMessage = 'Done!',
this.failedMessage = 'Failed!',
});

final String inProgressMessage;
final String doneMessage;
final String failedMessage;

Progress? progress;

void start() {
if (progress != null) {
throwToolExit('Spinner already started');
}

progress = interaction.progress(inProgressMessage);
}

void done() {
progress?.complete(doneMessage);
}

void failed() {
progress?.fail(failedMessage);
}
}
8 changes: 3 additions & 5 deletions lib/service/ssh_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,8 @@ class SshService {

logger.spaces();

final spinner = interaction.runSpinner(
inProgressMessage: 'Preparing SSH connection',
doneMessage: 'Preparing SSH connection completed',
failedMessage: 'Preparing SSH connection failed',
final progress = interaction.progress(
'Preparing SSH connection',
);

// create a directory in the user's home directory
Expand All @@ -252,7 +250,7 @@ class SshService {

await addSshKeyToAgent(sshKeys.privateKey);

spinner.done();
progress.complete('Preparing SSH connection completed');

await copySshKeyToRemote(
sshKeys.publicKey,
Expand Down
7 changes: 3 additions & 4 deletions lib/utils/process.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'dart:io';
import 'package:flutter_tools/src/base/io.dart';

import 'package:flutter_tools/src/base/process.dart';
import 'package:interact_cli/interact_cli.dart';
import 'package:process/process.dart';
import 'package:snapp_cli/commands/base_command.dart';

Expand All @@ -20,7 +19,7 @@ extension ProcessUtilsExt on ProcessUtils {
Duration? timeout = const Duration(seconds: 10),
String label = 'commandRunner',
}) async {
final spinnerState = spinner?.interact();
spinner?.start();

try {
final result = await run(
Expand All @@ -40,11 +39,11 @@ ${result.stderr.trim()}
''');
}

spinnerState?.done();
spinner?.done();

return parseResult?.call(result);
} catch (e, s) {
spinnerState?.failed();
spinner?.failed();

logger?.detail('$label Error: $e\n$s');

Expand Down
Loading

0 comments on commit 7480181

Please sign in to comment.