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);
            }
        }
Example #2
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);
        }
Example #3
0
        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));
            }
        }
Example #4
0
        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));
        }
Example #5
0
        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());
        }
Example #6
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));
            }
        }
Example #7
0
        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());
        }
Example #9
0
        // 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);
        }
Example #10
0
        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());
        }
Example #11
0
 private static string GetMemberName(MemberInfo member)
 {
     return(member.HasCustomAttribute <ParameterAttribute>()
         ? ParameterService.GetParameterMemberName(member)
         : member.Name);
 }