示例#1
0
        public Definition Load(TaskReference task)
        {
            // Validate args.
            Trace.Entering();
            ArgUtil.NotNull(task, nameof(task));

            // Initialize the definition wrapper object.
            var definition = new Definition() { Directory = GetDirectory(task) };

            // Deserialize the JSON.
            string file = Path.Combine(definition.Directory, Constants.Path.TaskJsonFile);
            Trace.Info($"Loading task definition '{file}'.");
            string json = File.ReadAllText(file);
            definition.Data = JsonConvert.DeserializeObject<DefinitionData>(json);

            // Replace the macros within the handler data sections.
            foreach (HandlerData handlerData in (definition.Data?.Execution?.All as IEnumerable<HandlerData> ?? new HandlerData[0]))
            {
                handlerData?.ReplaceMacros(HostContext, definition);
            }

            return definition;
        }
示例#2
0
 public void ReplaceMacros(IHostContext context, Definition definition)
 {
     var handlerVariables = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
     handlerVariables["currentdirectory"] = definition.Directory;
     VarUtil.ExpandValues(context, source: handlerVariables, target: Inputs);
 }
示例#3
0
        public async Task <Boolean> VerifyAsync(Definition definition, CancellationToken token)
        {
            ArgUtil.NotNull(definition, nameof(definition));

            // This is used for the Checkout task.
            // We can consider it verified since it's embedded in the Agent code.
            if (String.IsNullOrEmpty(definition.ZipPath))
            {
                return(true);
            }

            // Find NuGet
            String nugetPath = WhichUtil.Which("nuget", require: true);

            var           configurationStore = HostContext.GetService <IConfigurationStore>();
            AgentSettings settings           = configurationStore.GetSettings();
            SignatureVerificationSettings verificationSettings = settings.SignatureVerification;
            String taskZipPath   = definition.ZipPath;
            String taskNugetPath = definition.ZipPath.Replace(".zip", ".nupkg");

            // Rename .zip to .nupkg
            File.Move(taskZipPath, taskNugetPath);

            String arguments = $"verify -Signatures \"{taskNugetPath}\" -Verbosity Detailed";

            if (verificationSettings?.Fingerprints != null && verificationSettings.Fingerprints.Count > 0)
            {
                String fingerprint = String.Join(";", verificationSettings.Fingerprints);
                arguments += $" -CertificateFingerprint \"{fingerprint}\"";
            }

            Trace.Info($"nuget arguments: {arguments}");

            // Run nuget verify
            using (var processInvoker = HostContext.CreateService <IProcessInvoker>())
            {
                processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs args) =>
                {
                    if (!string.IsNullOrEmpty(args.Data))
                    {
                        Trace.Info(args.Data);
                    }
                };
                int exitCode = await processInvoker.ExecuteAsync(workingDirectory : HostContext.GetDirectory(WellKnownDirectory.Root),
                                                                 fileName : nugetPath,
                                                                 arguments : arguments,
                                                                 environment : null,
                                                                 requireExitCodeZero : false,
                                                                 outputEncoding : null,
                                                                 killProcessOnCancel : false,
                                                                 cancellationToken : token);

                // Rename back to zip
                File.Move(taskNugetPath, taskZipPath);

                if (exitCode != 0)
                {
                    return(false);
                }
            }

            return(true);
        }
示例#4
0
        public async Task RunAsync()
        {
            // Validate args.
            Trace.Entering();
            ArgUtil.NotNull(ExecutionContext, nameof(ExecutionContext));
            ArgUtil.NotNull(ExecutionContext.Variables, nameof(ExecutionContext.Variables));
            ArgUtil.NotNull(TaskInstance, nameof(TaskInstance));
            var taskManager    = HostContext.GetService <ITaskManager>();
            var handlerFactory = HostContext.GetService <IHandlerFactory>();

            // Set the task display name variable.
            ExecutionContext.Variables.Set(Constants.Variables.Task.DisplayName, DisplayName);

            // Load the task definition and choose the handler.
            // TODO: Add a try catch here to give a better error message.
            Definition definition = taskManager.Load(TaskInstance);

            ArgUtil.NotNull(definition, nameof(definition));
            HandlerData handlerData =
                definition.Data?.Execution?.All
                .OrderBy(x => !x.PreferredOnCurrentPlatform()) // Sort true to false.
                .ThenBy(x => x.Priority)
                .FirstOrDefault();

            if (handlerData == null)
            {
                string[] supportedHandlers;
#if OS_WINDOWS
                supportedHandlers = new string[] { "Node", "PowerShell3", "PowerShell", "AzurePowerShell", "PowerShellExe", "Process" };
#else
                supportedHandlers = new string[] { "Node" };
#endif
                throw new Exception(StringUtil.Loc("SupportedTaskHandlerNotFound", string.Join(", ", supportedHandlers)));
            }

            // Load the default input values from the definition.
            Trace.Verbose("Loading default inputs.");
            var inputs = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
            foreach (var input in (definition.Data?.Inputs ?? new TaskInputDefinition[0]))
            {
                string key = input?.Name?.Trim() ?? string.Empty;
                if (!string.IsNullOrEmpty(key))
                {
                    inputs[key] = input.DefaultValue?.Trim() ?? string.Empty;
                }
            }

            // Merge the instance inputs.
            Trace.Verbose("Loading instance inputs.");
            foreach (var input in (TaskInstance.Inputs as IEnumerable <KeyValuePair <string, string> > ?? new KeyValuePair <string, string> [0]))
            {
                string key = input.Key?.Trim() ?? string.Empty;
                if (!string.IsNullOrEmpty(key))
                {
                    inputs[key] = input.Value?.Trim() ?? string.Empty;
                }
            }

            // Expand the inputs.
            Trace.Verbose("Expanding inputs.");
            ExecutionContext.Variables.ExpandValues(target: inputs);
            VarUtil.ExpandEnvironmentVariables(HostContext, target: inputs);

            // Translate the server file path inputs to local paths.
            foreach (var input in definition.Data?.Inputs ?? new TaskInputDefinition[0])
            {
                if (string.Equals(input.InputType, TaskInputType.FilePath, StringComparison.OrdinalIgnoreCase))
                {
                    Trace.Verbose($"Translating file path input '{input.Name}': '{inputs[input.Name]}'");
                    inputs[input.Name] = TranslateFilePathInput(inputs[input.Name] ?? string.Empty);
                    Trace.Verbose($"Translated file path input '{input.Name}': '{inputs[input.Name]}'");
                }
            }

            // Expand the handler inputs.
            Trace.Verbose("Expanding handler inputs.");
            VarUtil.ExpandValues(HostContext, source: inputs, target: handlerData.Inputs);
            ExecutionContext.Variables.ExpandValues(target: handlerData.Inputs);

            // Create the handler.
            IHandler handler = handlerFactory.Create(
                ExecutionContext,
                handlerData,
                inputs,
                taskDirectory: definition.Directory,
                filePathInputRootDirectory: TranslateFilePathInput(string.Empty));

            // Run the task.
            await handler.RunAsync();
        }
示例#5
0
        public async Task RunAsync()
        {
            // Validate args.
            Trace.Entering();
            ArgUtil.NotNull(ExecutionContext, nameof(ExecutionContext));
            ArgUtil.NotNull(ExecutionContext.Variables, nameof(ExecutionContext.Variables));
            ArgUtil.NotNull(TaskInstance, nameof(TaskInstance));
            var taskManager    = HostContext.GetService <ITaskManager>();
            var handlerFactory = HostContext.GetService <IHandlerFactory>();

            // Load the task definition and choose the handler.
            // TODO: Add a try catch here to give a better error message.
            Definition definition = taskManager.Load(TaskInstance);

            ArgUtil.NotNull(definition, nameof(definition));
            HandlerData handlerData =
                definition.Data?.Execution?.All
                .OrderBy(x => !x.PreferredOnCurrentPlatform()) // Sort true to false.
                .ThenBy(x => x.Priority)
                .FirstOrDefault();

            if (handlerData == null)
            {
                // TODO: BETTER ERROR AND LOC
                throw new Exception("Supported handler not found.");
            }

            // Load the default input values from the definition.
            Trace.Verbose("Loading default inputs.");
            var inputs = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (var input in (definition.Data?.Inputs ?? new TaskInputDefinition[0]))
            {
                string key = input?.Name?.Trim() ?? string.Empty;
                if (!string.IsNullOrEmpty(key))
                {
                    inputs[key] = input.DefaultValue?.Trim() ?? string.Empty;
                }
            }

            // Merge the instance inputs.
            Trace.Verbose("Loading instance inputs.");
            foreach (var input in (TaskInstance.Inputs as IEnumerable <KeyValuePair <string, string> > ?? new KeyValuePair <string, string> [0]))
            {
                string key = input.Key?.Trim() ?? string.Empty;
                if (!string.IsNullOrEmpty(key))
                {
                    inputs[key] = input.Value?.Trim() ?? string.Empty;
                }
            }

            // Expand the inputs.
            Trace.Verbose("Expanding inputs.");
            ExecutionContext.Variables.ExpandValues(target: inputs);

            // Delegate to the JobExtension to fixup the file path inputs.
            foreach (var input in definition.Data?.Inputs ?? new TaskInputDefinition[0])
            {
                if (String.Equals(input.InputType, TaskInputType.FilePath, StringComparison.OrdinalIgnoreCase))
                {
                    Trace.Verbose($"Expanding filepath type input {input.Name}: {inputs[input.Name] ?? string.Empty}.");
                    inputs[input.Name] = ExpandFilePathInput(inputs[input.Name] ?? string.Empty);
                    Trace.Verbose($"Expanded filepath type input {input.Name}: {inputs[input.Name] ?? string.Empty}.");
                }
            }

            // Create the handler.
            IHandler handler = handlerFactory.Create(
                ExecutionContext,
                handlerData,
                inputs,
                taskDirectory: definition.Directory);

            // Run the task.
            await handler.RunAsync();
        }
示例#6
0
        public async Task RunAsync()
        {
            // Validate args.
            Trace.Entering();
            ArgUtil.NotNull(ExecutionContext, nameof(ExecutionContext));
            ArgUtil.NotNull(ExecutionContext.Variables, nameof(ExecutionContext.Variables));
            ArgUtil.NotNull(Task, nameof(Task));
            var taskManager    = HostContext.GetService <ITaskManager>();
            var handlerFactory = HostContext.GetService <IHandlerFactory>();

            // Set the task id and display name variable.
            using (var scope = ExecutionContext.Variables.CreateScope())
            {
                scope.Set(Constants.Variables.Task.DisplayName, DisplayName);
                scope.Set(WellKnownDistributedTaskVariables.TaskInstanceId, Task.Id.ToString("D"));
                scope.Set(WellKnownDistributedTaskVariables.TaskDisplayName, DisplayName);
                scope.Set(WellKnownDistributedTaskVariables.TaskInstanceName, Task.Name);

                // Load the task definition and choose the handler.
                // TODO: Add a try catch here to give a better error message.
                Definition definition = taskManager.Load(Task);
                ArgUtil.NotNull(definition, nameof(definition));

                // Verify task signatures if a fingerprint is configured for the Agent.
                var           configurationStore = HostContext.GetService <IConfigurationStore>();
                AgentSettings settings           = configurationStore.GetSettings();

                if (!String.IsNullOrEmpty(settings.Fingerprint))
                {
                    ISignatureService signatureService       = HostContext.CreateService <ISignatureService>();
                    Boolean           verificationSuccessful = await signatureService.VerifyAsync(definition, ExecutionContext.CancellationToken);

                    if (verificationSuccessful)
                    {
                        ExecutionContext.Output("Task signature verification successful.");

                        // Only extract if it's not the checkout task.
                        if (!String.IsNullOrEmpty(definition.ZipPath))
                        {
                            taskManager.Extract(ExecutionContext, Task);
                        }
                    }
                    else
                    {
                        throw new Exception("Task signature verification failed.");
                    }
                }

                // Print out task metadata
                PrintTaskMetaData(definition);

                ExecutionData currentExecution = null;
                switch (Stage)
                {
                case JobRunStage.PreJob:
                    currentExecution = definition.Data?.PreJobExecution;
                    break;

                case JobRunStage.Main:
                    currentExecution = definition.Data?.Execution;
                    break;

                case JobRunStage.PostJob:
                    currentExecution = definition.Data?.PostJobExecution;
                    break;
                }
                ;

                if ((currentExecution?.All.Any(x => x is PowerShell3HandlerData)).Value &&
                    (currentExecution?.All.Any(x => x is PowerShellHandlerData && x.Platforms != null && x.Platforms.Contains("windows", StringComparer.OrdinalIgnoreCase))).Value)
                {
                    // When task contains both PS and PS3 implementations, we will always prefer PS3 over PS regardless of the platform pinning.
                    Trace.Info("Ignore platform pinning for legacy PowerShell execution handler.");
                    var legacyPShandler = currentExecution?.All.Where(x => x is PowerShellHandlerData).FirstOrDefault();
                    legacyPShandler.Platforms = null;
                }

                var targetOS   = PlatformUtil.HostOS;
                var stepTarget = ExecutionContext.StepTarget();
                if (stepTarget != null)
                {
                    targetOS = stepTarget.ExecutionOS;
                }
                Trace.Info($"Get handler data for target platform {targetOS.ToString()}");

                HandlerData handlerData =
                    currentExecution?.All
                    .OrderBy(x => !x.PreferredOnPlatform(targetOS)) // Sort true to false.
                    .ThenBy(x => x.Priority)
                    .FirstOrDefault();
                if (handlerData == null)
                {
                    if (PlatformUtil.RunningOnWindows)
                    {
                        throw new Exception(StringUtil.Loc("SupportedTaskHandlerNotFoundWindows", $"{PlatformUtil.HostOS}({PlatformUtil.HostArchitecture})"));
                    }

                    throw new Exception(StringUtil.Loc("SupportedTaskHandlerNotFoundLinux"));
                }


                Variables runtimeVariables = ExecutionContext.Variables;
                IStepHost stepHost         = HostContext.CreateService <IDefaultStepHost>();

                // Setup container stephost and the right runtime variables for running job inside container.
                if (stepTarget is ContainerInfo containerTarget)
                {
                    if (handlerData is AgentPluginHandlerData)
                    {
                        // plugin handler always runs on the Host, the runtime variables needs to the variable works on the Host, ex: file path variable System.DefaultWorkingDirectory
                        Dictionary <string, VariableValue> variableCopy = new Dictionary <string, VariableValue>(StringComparer.OrdinalIgnoreCase);
                        foreach (var publicVar in ExecutionContext.Variables.Public)
                        {
                            variableCopy[publicVar.Key] = new VariableValue(stepTarget.TranslateToHostPath(publicVar.Value));
                        }
                        foreach (var secretVar in ExecutionContext.Variables.Private)
                        {
                            variableCopy[secretVar.Key] = new VariableValue(stepTarget.TranslateToHostPath(secretVar.Value), true);
                        }

                        List <string> expansionWarnings;
                        runtimeVariables = new Variables(HostContext, variableCopy, out expansionWarnings);
                        expansionWarnings?.ForEach(x => ExecutionContext.Warning(x));
                    }
                    else if (handlerData is NodeHandlerData || handlerData is Node10HandlerData || handlerData is PowerShell3HandlerData)
                    {
                        // Only the node, node10, and powershell3 handlers support running inside container.
                        // Make sure required container is already created.
                        ArgUtil.NotNullOrEmpty(containerTarget.ContainerId, nameof(containerTarget.ContainerId));
                        var containerStepHost = HostContext.CreateService <IContainerStepHost>();
                        containerStepHost.Container = containerTarget;
                        stepHost = containerStepHost;
                    }
                    else
                    {
                        throw new NotSupportedException(String.Format("Task '{0}' is using legacy execution handler '{1}' which is not supported in container execution flow.", definition.Data.FriendlyName, handlerData.GetType().ToString()));
                    }
                }

                // Load the default input values from the definition.
                Trace.Verbose("Loading default inputs.");
                var inputs = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                foreach (var input in (definition.Data?.Inputs ?? new TaskInputDefinition[0]))
                {
                    string key = input?.Name?.Trim() ?? string.Empty;
                    if (!string.IsNullOrEmpty(key))
                    {
                        inputs[key] = input.DefaultValue?.Trim() ?? string.Empty;
                    }
                }

                // Merge the instance inputs.
                Trace.Verbose("Loading instance inputs.");
                foreach (var input in (Task.Inputs as IEnumerable <KeyValuePair <string, string> > ?? new KeyValuePair <string, string> [0]))
                {
                    string key = input.Key?.Trim() ?? string.Empty;
                    if (!string.IsNullOrEmpty(key))
                    {
                        inputs[key] = input.Value?.Trim() ?? string.Empty;
                    }
                }

                // Expand the inputs.
                Trace.Verbose("Expanding inputs.");
                runtimeVariables.ExpandValues(target: inputs);
                VarUtil.ExpandEnvironmentVariables(HostContext, target: inputs);

                // Translate the server file path inputs to local paths.
                foreach (var input in definition.Data?.Inputs ?? new TaskInputDefinition[0])
                {
                    if (string.Equals(input.InputType, TaskInputType.FilePath, StringComparison.OrdinalIgnoreCase))
                    {
                        Trace.Verbose($"Translating file path input '{input.Name}': '{inputs[input.Name]}'");
                        inputs[input.Name] = stepHost.ResolvePathForStepHost(TranslateFilePathInput(inputs[input.Name] ?? string.Empty));
                        Trace.Verbose($"Translated file path input '{input.Name}': '{inputs[input.Name]}'");
                    }
                }

                // Load the task environment.
                Trace.Verbose("Loading task environment.");
                var environment = new Dictionary <string, string>(VarUtil.EnvironmentVariableKeyComparer);
                foreach (var env in (Task.Environment ?? new Dictionary <string, string>(0)))
                {
                    string key = env.Key?.Trim() ?? string.Empty;
                    if (!string.IsNullOrEmpty(key))
                    {
                        environment[key] = env.Value?.Trim() ?? string.Empty;
                    }
                }

                // Expand the inputs.
                Trace.Verbose("Expanding task environment.");
                runtimeVariables.ExpandValues(target: environment);
                VarUtil.ExpandEnvironmentVariables(HostContext, target: environment);

                // Expand the handler inputs.
                Trace.Verbose("Expanding handler inputs.");
                VarUtil.ExpandValues(HostContext, source: inputs, target: handlerData.Inputs);
                runtimeVariables.ExpandValues(target: handlerData.Inputs);

                // Get each endpoint ID referenced by the task.
                var endpointIds = new List <Guid>();
                foreach (var input in definition.Data?.Inputs ?? new TaskInputDefinition[0])
                {
                    if ((input.InputType ?? string.Empty).StartsWith("connectedService:", StringComparison.OrdinalIgnoreCase))
                    {
                        string inputKey = input?.Name?.Trim() ?? string.Empty;
                        string inputValue;
                        if (!string.IsNullOrEmpty(inputKey) &&
                            inputs.TryGetValue(inputKey, out inputValue) &&
                            !string.IsNullOrEmpty(inputValue))
                        {
                            foreach (string rawId in inputValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                            {
                                Guid parsedId;
                                if (Guid.TryParse(rawId.Trim(), out parsedId) && parsedId != Guid.Empty)
                                {
                                    endpointIds.Add(parsedId);
                                }
                            }
                        }
                    }
                }

                if (endpointIds.Count > 0 &&
                    (runtimeVariables.GetBoolean(WellKnownDistributedTaskVariables.RestrictSecrets) ?? false) &&
                    (runtimeVariables.GetBoolean(Microsoft.TeamFoundation.Build.WebApi.BuildVariables.IsFork) ?? false))
                {
                    ExecutionContext.Result     = TaskResult.Skipped;
                    ExecutionContext.ResultCode = $"References service endpoint. PRs from repository forks are not allowed to access secrets in the pipeline. For more information see https://go.microsoft.com/fwlink/?linkid=862029 ";
                    return;
                }

                // Get the endpoints referenced by the task.
                var endpoints = (ExecutionContext.Endpoints ?? new List <ServiceEndpoint>(0))
                                .Join(inner: endpointIds,
                                      outerKeySelector: (ServiceEndpoint endpoint) => endpoint.Id,
                                      innerKeySelector: (Guid endpointId) => endpointId,
                                      resultSelector: (ServiceEndpoint endpoint, Guid endpointId) => endpoint)
                                .ToList();

                // Add the system endpoint.
                foreach (ServiceEndpoint endpoint in (ExecutionContext.Endpoints ?? new List <ServiceEndpoint>(0)))
                {
                    if (string.Equals(endpoint.Name, WellKnownServiceEndpointNames.SystemVssConnection, StringComparison.OrdinalIgnoreCase))
                    {
                        endpoints.Add(endpoint);
                        break;
                    }
                }

                // Get each secure file ID referenced by the task.
                var secureFileIds = new List <Guid>();
                foreach (var input in definition.Data?.Inputs ?? new TaskInputDefinition[0])
                {
                    if (string.Equals(input.InputType ?? string.Empty, "secureFile", StringComparison.OrdinalIgnoreCase))
                    {
                        string inputKey = input?.Name?.Trim() ?? string.Empty;
                        string inputValue;
                        if (!string.IsNullOrEmpty(inputKey) &&
                            inputs.TryGetValue(inputKey, out inputValue) &&
                            !string.IsNullOrEmpty(inputValue))
                        {
                            foreach (string rawId in inputValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                            {
                                Guid parsedId;
                                if (Guid.TryParse(rawId.Trim(), out parsedId) && parsedId != Guid.Empty)
                                {
                                    secureFileIds.Add(parsedId);
                                }
                            }
                        }
                    }
                }

                if (secureFileIds.Count > 0 &&
                    (runtimeVariables.GetBoolean(WellKnownDistributedTaskVariables.RestrictSecrets) ?? false) &&
                    (runtimeVariables.GetBoolean(Microsoft.TeamFoundation.Build.WebApi.BuildVariables.IsFork) ?? false))
                {
                    ExecutionContext.Result     = TaskResult.Skipped;
                    ExecutionContext.ResultCode = $"References secure file. PRs from repository forks are not allowed to access secrets in the pipeline. For more information see https://go.microsoft.com/fwlink/?linkid=862029";
                    return;
                }

                // Get the endpoints referenced by the task.
                var secureFiles = (ExecutionContext.SecureFiles ?? new List <SecureFile>(0))
                                  .Join(inner: secureFileIds,
                                        outerKeySelector: (SecureFile secureFile) => secureFile.Id,
                                        innerKeySelector: (Guid secureFileId) => secureFileId,
                                        resultSelector: (SecureFile secureFile, Guid secureFileId) => secureFile)
                                  .ToList();

                // Set output variables.
                foreach (var outputVar in definition.Data?.OutputVariables ?? new OutputVariable[0])
                {
                    if (outputVar != null && !string.IsNullOrEmpty(outputVar.Name))
                    {
                        ExecutionContext.OutputVariables.Add(outputVar.Name);
                    }
                }

                // translate inputs
                inputs = inputs.ToDictionary(kvp => kvp.Key, kvp => ExecutionContext.TranslatePathForStepTarget(kvp.Value));

                // Create the handler.
                IHandler handler = handlerFactory.Create(
                    ExecutionContext,
                    Task.Reference,
                    stepHost,
                    endpoints,
                    secureFiles,
                    handlerData,
                    inputs,
                    environment,
                    runtimeVariables,
                    taskDirectory: definition.Directory);

                // Run the task.
                await handler.RunAsync();
            }
        }
示例#7
0
        public void ReplacesMultipleMacroInstances()
        {
            try
            {
                // Arrange.
                Setup();
                const string Directory = "Some directory";
                Definition definition = new Definition() { Directory = Directory };
                NodeHandlerData node = new NodeHandlerData()
                {
                    Target = @"$(CuRrEnTdIrEcToRy)$(CuRrEnTdIrEcToRy)\Some node target",
                };

                // Act.
                node.ReplaceMacros(_hc, definition);

                // Assert.
                Assert.Equal($@"{Directory}{Directory}\Some node target", node.Target);
            }
            finally
            {
                Teardown();
            }
        }
示例#8
0
        public void ReplacesMacrosAndPreventsInfiniteRecursion()
        {
            try
            {
                // Arrange.
                Setup();
                string directory = "$(currentdirectory)$(currentdirectory)";
                Definition definition = new Definition() { Directory = directory };
                NodeHandlerData node = new NodeHandlerData()
                {
                    Target = @"$(currentDirectory)\Some node target",
                };

                // Act.
                node.ReplaceMacros(_hc, definition);

                // Assert.
                Assert.Equal($@"{directory}\Some node target", node.Target);
            }
            finally
            {
                Teardown();
            }
        }
示例#9
0
        public void ReplacesMacros()
        {
            try
            {
                // Arrange.
                Setup();
                const string Directory = "Some directory";
                Definition definition = new Definition() { Directory = Directory };
                NodeHandlerData node = new NodeHandlerData()
                {
                    Target = @"$(CuRrEnTdIrEcToRy)\Some node target",
                    WorkingDirectory = @"$(CuRrEnTdIrEcToRy)\Some node working directory",
                };
                ProcessHandlerData process = new ProcessHandlerData()
                {
                    ArgumentFormat = @"$(CuRrEnTdIrEcToRy)\Some process argument format",
                    Target = @"$(CuRrEnTdIrEcToRy)\Some process target",
                    WorkingDirectory = @"$(CuRrEnTdIrEcToRy)\Some process working directory",
                };

                // Act.
                node.ReplaceMacros(_hc, definition);
                process.ReplaceMacros(_hc, definition);

                // Assert.
                Assert.Equal($@"{Directory}\Some node target", node.Target);
                Assert.Equal($@"{Directory}\Some node working directory", node.WorkingDirectory);
                Assert.Equal($@"{Directory}\Some process argument format", process.ArgumentFormat);
                Assert.Equal($@"{Directory}\Some process target", process.Target);
                Assert.Equal($@"{Directory}\Some process working directory", process.WorkingDirectory);
            }
            finally
            {
                Teardown();
            }
        }