replaceVariables method
Iterable<ResolveScript>
replaceVariables(
- String command, {
- required Map<
String, String?> sipVariables, - required ScriptsConfig config,
- required Script script,
- EnvConfig? envConfigOfParent,
- 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),
].combine(directory: directory),
script: script,
needsRunBeforeNext: false,
);
return;
}
Iterable<ResolveScript> resolvedCommands = [
ResolveScript.command(
command: command,
envConfig: null,
script: script,
needsRunBeforeNext: false,
),
];
final resolvedEnvCommands = <EnvConfig?>{};
final parentEnvConfig = script.envConfig(directory);
for (final match in matches) {
final variable = match.group(1);
final partToReplace = match.group(0)!;
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');
}
final replacedScripts = replace(
found,
config,
flags: flags,
parentEnvConfig: parentEnvConfig,
);
for (final replaced in replacedScripts) {
resolvedEnvCommands.add(replaced.envConfig);
final commandsToCopy = [...resolvedCommands];
final copied = List<ResolveScript>.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 copy = commandsToCopy[commandsToCopyIndex].copy()
..replaceCommandPart(partToReplace, command);
return copy;
});
resolvedCommands = copied;
}
continue;
}
if (variable.startsWith('-')) {
// flags are optional, so if not found, replace with empty string
final flag = flags?[variable] ?? '';
for (final command in resolvedCommands) {
command.replaceCommandPart(partToReplace, flag);
}
continue;
}
final sipValue = sipVariables[variable];
if (sipValue == null) {
throw Exception('Variable $variable is not defined');
}
for (final command in resolvedCommands) {
command.replaceCommandPart(partToReplace, sipValue);
}
}
final commandsWithEnv = resolvedCommands
.map(
(e) => e.copy(
envConfig: resolvedEnvCommands.combine(directory: directory),
),
)
.toList();
if (script.commands.length == 1) {
yield* commandsWithEnv;
return;
}
final envCommandIndex = script.env?.commands.indexOf(command) ?? -1;
if (envCommandIndex != -1) {
yield* commandsWithEnv;
return;
}
final commandIndex = script.commands.indexOf(command);
if (commandIndex == -1) {
throw Exception('Command $command not found in script ${script.name}');
}
final hasConcurrency = script.commands
.elementAt(commandIndex)
.contains(Identifiers.concurrent);
if (hasConcurrency) {
yield* commandsWithEnv;
return;
}
if (commandsWithEnv case [final command]) {
yield command;
return;
}
if (commandsWithEnv.isEmpty) {
return;
}
final commands = commandsWithEnv.toList();
final last = commands.removeLast();
yield* commands;
yield last.copy(needsRunBeforeNext: true);
}