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, ReflectionService.Convert(value, memberType)); } }
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) { Logger.Warn("Build invocation changed. Starting over..."); return(new string[0]); } return(previousBuild.Skip(1).ToArray()); } var previouslyExecutedTargets = GetPreviouslyExecutedTargets(); File.WriteAllLines(BuildAttemptFile, new[] { invocationHash }); return(previouslyExecutedTargets); }
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 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 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()); }
// 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); }
private static string GetMemberName(MemberInfo member) { return(member.HasCustomAttribute <ParameterAttribute>() ? ParameterService.GetParameterMemberName(member) : member.Name); }