Skip to content

Commit

Permalink
Merge pull request #399 from leoafarias/feature/exec-command
Browse files Browse the repository at this point in the history
Implementing exec command
  • Loading branch information
leoafarias authored Mar 10, 2022
2 parents 7b3ed8e + d374571 commit 9b126b5
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 14 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 2.3.0-dev.0

- Implemented `fvm exec` command. Execute terminal commands with the configured Flutter/Dart SDK version in the environment.
- Use command will install configured version by default if not version is provided.

## 2.2.6

- Fixed issue with routing to older Dart SDK directory path (before 1.17.5)
Expand Down
2 changes: 1 addition & 1 deletion lib/src/commands/dart_command.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:args/args.dart';
import 'package:fvm/src/services/cache_service.dart';

import '../models/valid_version_model.dart';
import '../services/cache_service.dart';
import '../services/project_service.dart';
import '../utils/commands.dart';
import '../utils/logger.dart';
Expand Down
2 changes: 1 addition & 1 deletion lib/src/commands/destroy_command.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:fvm/src/utils/logger.dart';
import 'package:io/io.dart';

import '../services/context.dart';
import '../utils/console_utils.dart';
import '../utils/logger.dart';
import 'base_command.dart';

/// Destroy FVM cache by deleting all Flutter SDK versions
Expand Down
57 changes: 57 additions & 0 deletions lib/src/commands/exec_command.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:args/args.dart';
import 'package:args/command_runner.dart';

import '../models/valid_version_model.dart';
import '../services/cache_service.dart';
import '../services/project_service.dart';
import '../utils/commands.dart';
import '../utils/logger.dart';
import '../workflows/ensure_cache.workflow.dart';
import 'base_command.dart';

/// Executes scripts with the configured Flutter SDK
class ExecCommand extends BaseCommand {
@override
final name = 'exec';
@override
final description = 'Executes scripts with the configured Flutter SDK';
@override
final argParser = ArgParser.allowAnything();

/// Constructor
ExecCommand();

@override
Future<int> run() async {
final version = await ProjectService.findVersion();

if (argResults!.rest.isEmpty) {
throw UsageException(
'No command was provided to be executed',
usage,
);
}

final cmd = argResults!.rest[0];

// Removes version from first arg
final execArgs = [...argResults!.rest]..removeAt(0);

if (version != null) {
final validVersion = ValidVersion(version);
// Will install version if not already instaled
final cacheVersion = await ensureCacheWorkflow(validVersion);

logger.trace('fvm: running version "$version"\n');
// If its not a channel silence version check

// Runs exec command with pinned version
return await execCmd(cmd, cacheVersion, execArgs);
} else {
// Try to get fvm global version
final cacheVersion = await CacheService.getGlobal();

return await execCmd(cmd, cacheVersion, execArgs);
}
}
}
11 changes: 8 additions & 3 deletions lib/src/models/cache_version_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,21 @@ class CacheVersion {
}

/// Returns dart exec file for cache version
String get dartExec {
String get dartBinPath {
/// Get old bin path
/// Before version 1.17.5 dart path was bin/cache/dart-sdk/bin
if (hasOldBinPath) {
return join(binPath, 'cache', 'dart-sdk', 'bin', dartBinFileName);
return join(binPath, 'cache', 'dart-sdk', 'bin');
} else {
return join(binPath, dartBinFileName);
return binPath;
}
}

/// Returns dart exec file for cache version
String get dartExec {
return join(dartBinPath, dartBinFileName);
}

/// Returns flutter exec file for cache version
String get flutterExec {
return join(binPath, flutterBinFileName);
Expand Down
2 changes: 2 additions & 0 deletions lib/src/models/config_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class FvmConfig {
if (env.isEmpty) {
return null;
}

return env;
}

/// Check if config file exists
Expand Down
2 changes: 2 additions & 0 deletions lib/src/runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'commands/config_command.dart';
import 'commands/dart_command.dart';
import 'commands/destroy_command.dart';
import 'commands/doctor_command.dart';
import 'commands/exec_command.dart';
import 'commands/flavor_command.dart';
import 'commands/flutter_command.dart';
import 'commands/global_command.dart';
Expand Down Expand Up @@ -57,6 +58,7 @@ class FvmCommandRunner extends CommandRunner<int> {
addCommand(ConfigCommand());
addCommand(FlavorCommand());
addCommand(DestroyCommand());
addCommand(ExecCommand());
}

@override
Expand Down
33 changes: 31 additions & 2 deletions lib/src/utils/commands.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,36 @@ Future<int> flutterCmd(
);
}

/// Exec commands with the Flutter env
Future<int> execCmd(
String execPath,
CacheVersion? version,
List<String> args,
) async {
// Update environment variables
final binPath = version?.binPath ?? whichSync('flutter') ?? '';
final dartBinPath = version?.dartBinPath ?? whichSync('dart') ?? '';

var environment = updateFlutterEnvVariables(binPath);

// Update environment with dart exec path
environment = updateDartEnvVariables(dartBinPath, environment);

// Run command
return await _runCmd(
execPath,
args: args,
environment: environment,
checkIfExecutable: false,
);
}

/// Runs dart cmd
Future<int> dartCmd(CacheVersion version, List<String> args) async {
// Get exec path for dart
final execPath = version.dartExec;
// Update environment
final environment = updateDartEnvVariables(execPath);
final environment = updateDartEnvVariables(version.dartBinPath);

// Run command
return await _runCmd(
Expand Down Expand Up @@ -70,9 +94,14 @@ Future<int> _runCmd(
String execPath, {
List<String> args = const [],
Map<String, String>? environment,
// Checks if path can be executed
bool checkIfExecutable = true,
}) async {
// Project again a non executable path
await Guards.canExecute(execPath, args);

if (checkIfExecutable) {
await Guards.canExecute(execPath, args);
}

final processManager = ProcessManager();

Expand Down
19 changes: 12 additions & 7 deletions lib/src/utils/helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,25 @@ Future<void> createLink(Link source, FileSystemEntity target) async {
}

/// Returns updated environment for Flutter with [execPath]
Map<String, String> updateFlutterEnvVariables(String binPath) {
return _updateEnvVariables('flutter', binPath);
Map<String, String> updateFlutterEnvVariables(String binPath,
[Map<String, String>? env]) {
return _updateEnvVariables('flutter', binPath, env: env);
}

/// Returns updated environment for Dark with [binPath]
Map<String, String> updateDartEnvVariables(String binPath) {
return _updateEnvVariables('dart', binPath);
Map<String, String> updateDartEnvVariables(String binPath,
[Map<String, String>? env]) {
return _updateEnvVariables('dart', binPath, env: env);
}

Map<String, String> _updateEnvVariables(
String key,
String binPath,
) {
final envPath = kEnvVars['PATH'] ?? '';
String binPath, {
Map<String, String>? env,
}) {
// Use env passed in param or get from current process
final envMap = env ?? kEnvVars;
final envPath = envMap['PATH'] ?? '';

/// Remove exec path that does not match
final pathEnvList = envPath
Expand Down

0 comments on commit 9b126b5

Please sign in to comment.