replaceVariables method

Iterable<ResolveScript> replaceVariables(
  1. String command, {
  2. required Map<String, String?> sipVariables,
  3. required ScriptsConfig config,
  4. required Script script,
  5. EnvConfig? envConfigOfParent,
  6. OptionalFlags? flags,
})

Implementation

Iterable<ResolveScript> replaceVariables(
  String command, {
  required Map<String, String?> sipVariables,
  required ScriptsConfig config,
  required Script script,
  EnvConfig? envConfigOfParent,
  OptionalFlags? flags,
}) sync* {
  final matches = variablePattern.allMatches(command);

  if (matches.isEmpty) {
    yield ResolveScript.command(
      command: command,
      envConfig: [
        envConfigOfParent,
        script.envConfig(directory: directory),
      ].combine(directory: directory),
      script: script,
    );

    return;
  }

  Iterable<String> resolvedCommands = [command];
  final resolvedEnvCommands = <EnvConfig?>{};

  final parentEnvConfig = script.envConfig(directory: directory);

  for (final match in matches) {
    final variable = match.group(1);

    if (variable == null) {
      continue;
    }

    if (variable.startsWith(r'$')) {
      final scriptPath = variable.substring(1).split(':');

      final found = config.find(scriptPath);

      if (found == null) {
        throw Exception('Script path $variable is invalid');
      }

      for (final replaced in replace(
        found,
        config,
        flags: flags,
        parentEnvConfig: parentEnvConfig,
      )) {
        resolvedEnvCommands.add(replaced.envConfig);

        final commandsToCopy = [...resolvedCommands];

        final copied = List.generate(
            resolvedCommands.length * replaced.resolvedScripts.length,
            (index) {
          final commandIndex = index % replaced.resolvedScripts.length;
          final command =
              replaced.resolvedScripts.elementAt(commandIndex).command;

          if (command == null) {
            throw Exception('Command is null');
          }

          final commandsToCopyIndex =
              index ~/ replaced.resolvedScripts.length;
          final commandsToCopyCommand = commandsToCopy[commandsToCopyIndex];

          return commandsToCopyCommand.replaceAll(match.group(0)!, command);
        });

        resolvedCommands = copied;
      }

      continue;
    }

    if (variable.startsWith('-')) {
      // flags are optional, so if not found, replace with empty string
      final flag = flags?[variable] ?? '';

      resolvedCommands = resolvedCommands.map(
        (e) => e.replaceAll(match.group(0)!, flag),
      );

      continue;
    }

    final sipValue = sipVariables[variable];

    if (sipValue == null) {
      throw Exception('Variable $variable is not defined');
    }

    resolvedCommands = resolvedCommands.map(
      (e) => e.replaceAll(match.group(0)!, sipValue),
    );
  }

  for (final command in resolvedCommands) {
    yield ResolveScript.command(
      command: command,
      envConfig: resolvedEnvCommands.combine(directory: directory),
      script: script,
    );
  }
}