public void OnBeforeLogo( NukeBuild build, IReadOnlyCollection <ExecutableTarget> executableTargets) { var completionItems = new SortedDictionary <string, string[]>(); var targetNames = build.ExecutableTargets.Select(x => x.Name).OrderBy(x => x).ToList(); completionItems[Constants.InvokedTargetsParameterName] = targetNames.ToArray(); completionItems[Constants.SkippedTargetsParameterName] = targetNames.ToArray(); var parameters = InjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false); foreach (var parameter in parameters) { var parameterName = ParameterService.GetParameterMemberName(parameter); if (completionItems.ContainsKey(parameterName)) { continue; } var subItems = ParameterService.GetParameterValueSet(parameter, build)?.Select(x => x.Text); completionItems[parameterName] = subItems?.ToArray(); } SerializationTasks.YamlSerializeToFile(completionItems, Constants.GetCompletionFile(NukeBuild.RootDirectory)); if (EnvironmentInfo.GetParameter <bool>(Constants.CompletionParameterName)) { Environment.Exit(exitCode: 0); } }
private static IReadOnlyCollection <string> UpdateInvocationHash(NukeBuild build) { var continueParameterName = ParameterService.GetParameterMemberName(() => build.Continue); var invocation = EnvironmentInfo.CommandLineArguments .Where(x => !x.StartsWith("-") || x.TrimStart("-").EqualsOrdinalIgnoreCase(continueParameterName)) .JoinSpace(); var invocationHash = invocation.GetMD5Hash(); IReadOnlyCollection <string> GetPreviouslyExecutedTargets() { if (!build.Continue || !File.Exists(BuildAttemptFile)) { return(new string[0]); } var previousBuild = File.ReadAllLines(BuildAttemptFile); if (previousBuild.FirstOrDefault() != invocationHash) { Log.Warning("Build invocation changed. Restarting ..."); return(new string[0]); } return(previousBuild.Skip(1).ToArray()); } var previouslyExecutedTargets = GetPreviouslyExecutedTargets(); File.WriteAllLines(BuildAttemptFile, new[] { invocationHash }); return(previouslyExecutedTargets); }
private static void TryInjectValueInteractive(MemberInfo member, NukeBuild build) { if (!member.HasCustomAttribute <ParameterAttribute>()) { return; } if (member is PropertyInfo property && !property.CanWrite) { return; } var memberType = member.GetMemberType(); var nameOrDescription = ParameterService.GetParameterDescription(member) ?? ParameterService.GetParameterMemberName(member); var text = $"{nameOrDescription.TrimEnd('.')}:"; while (member.GetValue(build) == null) { var valueSet = ParameterService.GetParameterValueSet(member, build); var value = valueSet == null ? ConsoleUtility.PromptForInput(text, defaultValue : null) : ConsoleUtility.PromptForChoice(text, valueSet.Select(x => (x.Object, x.Text)).ToArray()); member.SetValue(build, ReflectionUtility.Convert(value, memberType)); } }
private static void WriteCompletionFile(NukeBuild build) { var completionItems = new SortedDictionary <string, string[]>(); var targets = build.ExecutableTargets.OrderBy(x => x.Name).ToList(); completionItems[InvokedTargetsParameterName] = targets.Where(x => x.Listed).Select(x => x.Name).ToArray(); completionItems[SkippedTargetsParameterName] = targets.Select(x => x.Name).ToArray(); var parameters = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false); foreach (var parameter in parameters) { var parameterName = ParameterService.GetParameterMemberName(parameter); if (completionItems.ContainsKey(parameterName)) { continue; } var subItems = ParameterService.GetParameterValueSet(parameter, build)?.Select(x => x.Text); completionItems[parameterName] = subItems?.ToArray(); } SerializationTasks.YamlSerializeToFile(completionItems, GetCompletionFile(NukeBuild.RootDirectory)); }
public static string GetParametersText(NukeBuild build) { var defaultTarget = build.ExecutableTargets.SingleOrDefault(x => x.IsDefault); var builder = new StringBuilder(); var parameters = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false) .OrderBy(x => x.Name).ToList(); var padRightParameter = Math.Max(parameters.Max(x => x.Name.Length), val2: 16); void PrintParameter(MemberInfo parameter) { var description = SplitLines( // TODO: remove ParameterService.GetParameterDescription(parameter) ?.Replace("{default_target}", defaultTarget?.Name).Append(".") ?? "<no description>"); var parameterName = ParameterService.GetParameterDashedName(parameter); builder.AppendLine($" --{parameterName.PadRight(padRightParameter)} {description.First()}"); foreach (var line in description.Skip(count: 1)) { builder.AppendLine($"{new string(c: ' ', count: padRightParameter + 6)}{line}"); } } builder.AppendLine("Parameters:"); var customParameters = parameters.Where(x => x.DeclaringType != typeof(NukeBuild)).ToList(); if (customParameters.Count > 0) { builder.AppendLine(); } foreach (var parameter in customParameters) { PrintParameter(parameter); } builder.AppendLine(); var inheritedParameters = parameters.Where(x => x.DeclaringType == typeof(NukeBuild)); foreach (var parameter in inheritedParameters) { PrintParameter(parameter); } return(builder.ToString()); }
private static void InjectValueInteractive(NukeBuild build, MemberInfo member) { var memberType = member.GetMemberType(); var nameOrDescription = ParameterService.GetParameterDescription(member) ?? ParameterService.GetParameterMemberName(member); var text = $"{nameOrDescription.TrimEnd('.')}:"; while (member.GetValue(build) == null) { var valueSet = ParameterService.GetParameterValueSet(member, build); var value = valueSet == null ? ConsoleUtility.PromptForInput(text, defaultValue : null) : ConsoleUtility.PromptForChoice(text, valueSet.Select(x => (x.Object, x.Text)).ToArray()); member.SetValue(build, ReflectionService.Convert(value, memberType)); } }
public void OnBuildCreated(NukeBuild build, IReadOnlyCollection <ExecutableTarget> executableTargets) { // TODO: probably remove if (!Directory.Exists(Constants.GetNukeDirectory(NukeBuild.RootDirectory))) { return; } var parameterMembers = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: true); var passwords = new Dictionary <string, string>(); IEnumerable <string> ConvertToArguments(string profile, string name, string[] values) { var member = parameterMembers.SingleOrDefault(x => ParameterService.GetParameterMemberName(x).EqualsOrdinalIgnoreCase(name)); var scalarType = member?.GetMemberType().GetScalarType(); var mustDecrypt = (member?.HasCustomAttribute <SecretAttribute>() ?? false) && !BuildServerConfigurationGeneration.IsActive; var decryptedValues = values.Select(x => mustDecrypt ? DecryptValue(profile, name, x) : x); var convertedValues = decryptedValues.Select(x => ConvertValue(scalarType, x)).ToList(); Log.Verbose("Passing value for {Member} ({Value})", member?.GetDisplayName() ?? "<unresolved>", !mustDecrypt ? convertedValues.JoinComma() : "secret"); return(new[] { $"--{ParameterService.GetParameterDashedName(name)}" }.Concat(convertedValues)); } string DecryptValue(string profile, string name, string value) => EncryptionUtility.Decrypt( value, passwords[profile] = passwords.GetValueOrDefault(profile) ?? EncryptionUtility.GetPassword(profile), name); // TODO: Abstract AbsolutePath/Solution/Project etc. string ConvertValue(Type scalarType, string value) => scalarType == typeof(AbsolutePath) || typeof(Solution).IsAssignableFrom(scalarType) || scalarType == typeof(Project) ? EnvironmentInfo.WorkingDirectory.GetUnixRelativePathTo(NukeBuild.RootDirectory / value) : value; var arguments = GetParameters().SelectMany(x => ConvertToArguments(x.Profile, x.Name, x.Values)).ToArray(); ParameterService.Instance.ArgumentsFromFilesService = new ParameterService(() => arguments, () => throw new NotSupportedException()); }
public void OnBuildCreated(NukeBuild build, IReadOnlyCollection <ExecutableTarget> executableTargets) { // TODO: probably remove if (!Directory.Exists(Constants.GetNukeDirectory(NukeBuild.RootDirectory))) { return; } var parameterMembers = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: true); var passwords = new Dictionary <string, byte[]>(); IEnumerable <string> ConvertToArguments(string profile, string name, string[] values) { var member = parameterMembers.SingleOrDefault(x => x.Name.EqualsOrdinalIgnoreCase(name)); var scalarType = member?.GetMemberType().GetScalarType(); var mustDecrypt = (member?.HasCustomAttribute <SecretAttribute>() ?? false) && !GenerationMode; var decryptedValues = values.Select(x => mustDecrypt ? DecryptValue(profile, name, x) : x); var convertedValues = decryptedValues.Select(x => ConvertValue(scalarType, x)); Logger.Trace($"Passing argument for '{name}'{(member != null ? $" on '{member.DeclaringType.NotNull().Name}'" : string.Empty)}."); return(new[] { $"--{ParameterService.GetParameterDashedName(name)}" }.Concat(convertedValues)); } string DecryptValue(string profile, string name, string value) => EncryptionUtility.Decrypt( value, passwords[profile] = passwords.GetValueOrDefault(profile) ?? Encoding.UTF8.GetBytes(EncryptionUtility.GetPassword(profile)), name); // TODO: Abstract AbsolutePath/Solution/Project etc. string ConvertValue(Type scalarType, string value) => scalarType == typeof(AbsolutePath) || typeof(Solution).IsAssignableFrom(scalarType) || scalarType == typeof(Project) ? EnvironmentInfo.WorkingDirectory.GetUnixRelativePathTo(NukeBuild.RootDirectory / value) : value; var arguments = GetParameters().SelectMany(x => ConvertToArguments(x.Profile, x.Name, x.Values)).ToArray(); ParameterService.Instance.ArgumentsFromFilesService = new ParameterService(() => arguments, () => throw new NotSupportedException()); }
// ReSharper disable once CognitiveComplexity public static JObject GetBuildSchema(NukeBuild build) { var parameters = ValueInjectionUtility .GetParameterMembers(build.GetType(), includeUnlisted: true) // .Where(x => x.DeclaringType != typeof(NukeBuild)) .Select(x => new { Name = ParameterService.GetParameterMemberName(x), Description = ParameterService.GetParameterDescription(x), MemberType = x.GetMemberType(), ScalarType = x.GetMemberType().GetScalarType(), EnumValues = ParameterService.GetParameterValueSet(x, build)?.Select(x => x.Text), IsRequired = x.HasCustomAttribute <RequiredAttribute>(), IsSecret = x.HasCustomAttribute <SecretAttribute>() }).ToList(); string GetJsonType(Type type) => type.IsCollectionLike() ? "array" : type.GetScalarType() == typeof(int) ? "integer" : type.GetScalarType() == typeof(bool) ? "boolean" : "string"; var schema = JObject.Parse(@" { ""$schema"": ""http://json-schema.org/draft-04/schema#"", ""title"": ""Build Schema"", ""$ref"": ""#/definitions/build"", ""definitions"": { ""build"": { ""type"": ""object"", ""properties"": { } } } } "); var properties = schema["definitions"].NotNull()["build"].NotNull()["properties"].NotNull(); foreach (var parameter in parameters) { var property = properties[parameter.Name] = new JObject(); property["type"] = GetJsonType(parameter.MemberType); if (parameter.Description != null) { property["description"] = parameter.Description; } if (parameter.IsSecret) { property["default"] = "Secrets must be entered via 'nuke :secrets [profile]'"; } if (parameter.EnumValues != null && !parameter.MemberType.IsCollectionLike()) { property["enum"] = new JArray(parameter.EnumValues); } if (parameter.MemberType.IsCollectionLike()) { property["items"] = new JObject(); property["items"].NotNull()["type"] = GetJsonType(parameter.ScalarType); if (parameter.EnumValues != null) { property["items"].NotNull()["enum"] = new JArray(parameter.EnumValues); } } } return(schema); }
public static string GetParametersText(NukeBuild build) { var defaultTargets = build.ExecutableTargets.Where(x => x.IsDefault).Select(x => x.Name).ToList(); var builder = new StringBuilder(); var parameters = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false); var padRightParameter = Math.Max(parameters.Max(x => ParameterService.GetParameterDashedName(x).Length), val2: 16); List <string> SplitLines(string text) { var words = new Queue <string>(text.Split(' ').ToList()); var lines = new List <string> { string.Empty }; foreach (var word in words) { var nextLength = padRightParameter + 6 + lines.Last().Length + word.Length; if (nextLength >= Console.BufferWidth || nextLength > 90) { lines.Add(string.Empty); } lines[lines.Count - 1] = $"{lines.Last()} {word}"; } return(lines); } void PrintParameter(MemberInfo parameter) { var description = SplitLines( // TODO: remove ParameterService.GetParameterDescription(parameter) ?.Replace("{default_target}", defaultTargets.Count > 0 ? defaultTargets.JoinCommaSpace() : "<none>") .TrimEnd(".").Append(".") ?? "<no description>"); var parameterName = ParameterService.GetParameterDashedName(parameter); builder.AppendLine($" --{parameterName.PadRight(padRightParameter)} {description.First()}"); foreach (var line in description.Skip(count: 1)) { builder.AppendLine($"{new string(c: ' ', count: padRightParameter + 6)}{line}"); } } builder.AppendLine("Parameters:"); var customParameters = parameters.Where(x => x.DeclaringType != typeof(NukeBuild)).ToList(); if (customParameters.Count > 0) { builder.AppendLine(); } foreach (var parameter in customParameters) { PrintParameter(parameter); } builder.AppendLine(); var inheritedParameters = parameters.Where(x => x.DeclaringType == typeof(NukeBuild)); foreach (var parameter in inheritedParameters) { PrintParameter(parameter); } return(builder.ToString()); }
private static string GetMemberName(MemberInfo member) { return(member.HasCustomAttribute <ParameterAttribute>() ? ParameterService.GetParameterMemberName(member) : member.Name); }