Beispiel #1
0
        private static IDictionary <string, string> GetBuildProperties(NukeBuild build)
        {
            var startTimeString = EnvironmentInfo.Variables.GetValueOrDefault(Constants.GlobalToolStartTimeEnvironmentKey);
            var compileTime     = startTimeString != null
                ? DateTime.Now.Subtract(DateTime.Parse(startTimeString))
                : default(TimeSpan?);

            return(new Dictionary <string, string>
            {
                ["compile_time"] = compileTime?.TotalSeconds.ToString("F0"),
                ["target_framework"] = EnvironmentInfo.Framework.ToString(),
                ["host"] = GetTypeName(NukeBuild.Host),
                ["build_type"] = NukeBuild.BuildProjectFile != null ? "Project" : "Global Tool",
                ["num_targets"] = build.ExecutableTargets.Count.ToString(),
                ["num_custom_extensions"] = build.BuildExtensions.Select(x => x.GetType()).Count(IsCustomType).ToString(),
                ["num_custom_components"] = build.GetType().GetInterfaces().Count(IsCustomType).ToString(),
                ["num_partitioned_targets"] = build.ExecutableTargets.Count(x => x.PartitionSize.HasValue).ToString(),
                ["num_secrets"] = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: true)
                                  .Count(x => x.HasCustomAttribute <SecretAttribute>()).ToString(),
                ["config_generators"] = build.GetType().GetCustomAttributes <ConfigurationAttributeBase>()
                                        .Select(GetTypeName).Distinct().OrderBy(x => x).JoinCommaSpace(),
                ["build_components"] = build.GetType().GetInterfaces().Where(x => IsCommonType(x) && x != typeof(INukeBuild))
                                       .Select(GetTypeName).Distinct().OrderBy(x => x).JoinCommaSpace()
            });
        }
Beispiel #2
0
        public static void SetValue(NukeBuild build, string memberName, object value)
        {
            var member = build.GetType().GetMember(memberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
                         .SingleOrDefault()
                         .NotNull($"Could not find member '{memberName}' on type '{build.GetType()}'.");

            SetValue(build, member, value);
        }
Beispiel #3
0
        public override ConfigurationEntity GetConfiguration(
            NukeBuild build,
            IReadOnlyCollection <ExecutableTarget> relevantTargets
            )
        {
            var paramList  = new List <AzurePipelinesParameter>();
            var parameters =
                build.GetType()
                .GetInterfaces()
                .SelectMany(x => x.GetMembers())
                .Concat(
                    build.GetType()
                    .GetMembers(
                        BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic |
                        BindingFlags.Public | BindingFlags.FlattenHierarchy
                        )
                    )
                .Where(x => x.GetCustomAttribute <ParameterAttribute>() != null);

            foreach (var parameter in parameters)
            {
                if (Parameters.Any(
                        z => z.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase) || z.Equals(
                            parameter.GetCustomAttribute <ParameterAttribute>()?.Name,
                            StringComparison.OrdinalIgnoreCase
                            )
                        ))
                {
                    var value = parameter.GetValue(build);
                    if (value is AbsolutePath)
                    {
                        value = null;
                    }

                    paramList.Add(
                        new AzurePipelinesParameter
                    {
                        Name    = parameter.GetCustomAttribute <ParameterAttribute>()?.Name ?? parameter.Name,
                        Default = value?.ToString() ?? "",
                    }
                        );
                }
            }

            var lookupTable = new LookupTable <ExecutableTarget, AzurePipelinesStep>();
            var steps       = relevantTargets
                              .Select(x => (ExecutableTarget: x, Job: GetStep(x, relevantTargets, lookupTable)))
                              .ForEachLazy(x => lookupTable.Add(x.ExecutableTarget, x.Job))
                              .Select(x => x.Job).ToArray();

            return(new AzurePipelinesSteps
            {
                Parameters = paramList.ToArray(),
                Steps = steps
            });
        }
        protected virtual IEnumerable <GithubActionsNukeParameter> GetParameters(NukeBuild build)
        {
            var parameters =
                build.GetType().GetMembers(
                    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public |
                    BindingFlags.FlattenHierarchy
                    )
                .Where(x => x.GetCustomAttribute <ParameterAttribute>() != null);

            foreach (var parameter in parameters)
            {
                if (Parameters.Any(
                        z => z.Equals(parameter.Name, StringComparison.OrdinalIgnoreCase) || z.Equals(
                            parameter.GetCustomAttribute <ParameterAttribute>().Name,
                            StringComparison.OrdinalIgnoreCase
                            )
                        ))
                {
                    var value = parameter.GetValue(build);
                    if (value is AbsolutePath)
                    {
                        value = null;
                    }

                    yield return(new GithubActionsNukeParameter()
                    {
                        Name = parameter.GetCustomAttribute <ParameterAttribute>().Name ?? parameter.Name,
                        Default = value?.ToString() ?? "",
                    });
                }
            }
        }
Beispiel #5
0
        public static void ValidateRequirements(NukeBuild build, IReadOnlyCollection <ExecutableTarget> executingTargets)
        {
            foreach (var target in executingTargets)
            {
                foreach (var requirement in target.Requirements)
                {
                    if (requirement is Expression <Func <bool> > boolExpression)
                    {
                        // TODO: same as HasSkippingCondition.GetSkipReason
                        ControlFlow.Assert(boolExpression.Compile().Invoke(), $"Target '{target.Name}' requires '{requirement.Body}'.");
                    }
                    else if (IsMemberNull(requirement.GetMemberInfo(), build, target))
                    {
                        ControlFlow.Fail($"Target '{target.Name}' requires member '{requirement.GetMemberInfo().Name}' to be not null.");
                    }
                }
            }

            var requiredMembers = ValueInjectionUtility.GetInjectionMembers(build.GetType())
                                  .Select(x => x.Member)
                                  .Where(x => x.HasCustomAttribute <RequiredAttribute>());

            foreach (var member in requiredMembers)
            {
                if (IsMemberNull(member, build))
                {
                    ControlFlow.Fail($"Member '{member.Name}' is required to be not null.");
                }
            }
        }
        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);
            }
        }
Beispiel #7
0
        public static void ValidateRequirements(NukeBuild build)
        {
            foreach (var target in build.ExecutionPlan)
            {
                foreach (var requirement in target.Requirements)
                {
                    if (requirement is Expression <Func <bool> > boolExpression)
                    {
                        ControlFlow.Assert(boolExpression.Compile().Invoke(), $"Target '{target.Name}' requires '{requirement.Body}'.");
                    }
                    else if (IsMemberNull(requirement.GetMemberInfo(), build, target))
                    {
                        ControlFlow.Fail($"Target '{target.Name}' requires member '{requirement.GetMemberInfo().Name}' to be not null.");
                    }
                }
            }

            var requiredMembers = InjectionUtility.GetParameterMembers(build.GetType()).Where(x => x.HasCustomAttribute <RequiredAttribute>());

            foreach (var member in requiredMembers)
            {
                if (IsMemberNull(member, build))
                {
                    ControlFlow.Fail($"Member '{member.Name}' is required to be not null.");
                }
            }
        }
Beispiel #8
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));
        }
Beispiel #9
0
        public static void InjectValues(NukeBuild build)
        {
            var injectionMembers = build.GetType()
                                   .GetMembers(c_bindingFlags)
                                   .Where(x => x.GetCustomAttributes <InjectionAttributeBase>().Any()).ToList();

            foreach (var member in injectionMembers)
            {
                var attributes = member.GetCustomAttributes().OfType <InjectionAttributeBase>().ToList();
                if (attributes.Count == 0)
                {
                    continue;
                }
                ControlFlow.Assert(attributes.Count == 1, $"Member '{member.Name}' has multiple injection attributes applied.");

                var attribute  = attributes.Single();
                var memberType = (member as FieldInfo)?.FieldType ?? ((PropertyInfo)member).PropertyType;
                var value      = attribute.GetValue(member.Name, memberType);
                if (value == null)
                {
                    continue;
                }

                var valueType = value.GetType();
                ControlFlow.Assert(memberType.IsAssignableFrom(valueType),
                                   $"Field '{member.Name}' must be of type '{valueType.Name}' to get its valued injected from '{attribute.GetType().Name}'.");
                SetValue(build, member, value);
            }
        }
Beispiel #10
0
 protected virtual IEnumerable <TeamCityParameter> GetGlobalParameters(NukeBuild build, IReadOnlyCollection <ExecutableTarget> relevantTargets)
 {
     return(ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false)
            .Except(relevantTargets.SelectMany(x => x.Requirements
                                               .Where(y => !(y is Expression <Func <bool> >))
                                               .Select(y => y.GetMemberInfo())))
            .Where(x => x.DeclaringType != typeof(NukeBuild) || x.Name == nameof(NukeBuild.Verbosity))
            .Select(x => GetParameter(x, build, required: false)));
 }
Beispiel #11
0
        private static bool IsMemberNull(MemberInfo member, NukeBuild build, ExecutableTarget target = null)
        {
            member = member.DeclaringType != build.GetType()
                ? build.GetType().GetMember(member.Name).SingleOrDefault() ?? member
                : member;

            var from = target != null ? $"from target '{target.Name}' " : string.Empty;

            ControlFlow.Assert(member.HasCustomAttribute <ValueInjectionAttributeBase>(),
                               $"Member '{member.Name}' is required {from}but not marked with an injection attribute.");

            if (NukeBuild.Host == HostType.Console)
            {
                TryInjectValueInteractive(member, build);
            }

            return(member.GetValue(build) == null);
        }
Beispiel #12
0
        public static IReadOnlyCollection <MemberInfo> GetInjectionMembers(this NukeBuild build)
        {
            var members = build.GetType()
                          .GetMembers(ReflectionService.All)
                          .Where(x => x.GetCustomAttributes <InjectionAttributeBase>().Any()).ToList();

            var transitiveMembers = members
                                    .SelectMany(x => x.GetCustomAttributes <InjectionAttributeBase>())
                                    .SelectMany(x => x.GetType().GetMembers(ReflectionService.All))
                                    .Where(x => x.GetCustomAttributes <InjectionAttributeBase>().Any()).ToList();

            return(members.Concat(transitiveMembers).ToList());
        }
Beispiel #13
0
 protected virtual IEnumerable <TeamCityParameter> GetGlobalParameters(NukeBuild build, IReadOnlyCollection <ExecutableTarget> relevantTargets)
 {
     return(ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false)
            // TODO: except build.ExecutableTargets ?
            .Except(relevantTargets.SelectMany(x => x.Requirements
                                               .Where(y => y is not Expression <Func <bool> >)
                                               .Select(y => y.GetMemberInfo())))
            .Where(x => !x.HasCustomAttribute <SecretAttribute>())
            .Where(x => x.DeclaringType != typeof(NukeBuild) || x.Name == nameof(NukeBuild.Verbosity))
            .Select(x => GetParameter(x, build, required: false))
            .Concat(GetSecretParameters(build))
            .Concat(GetDefaultParameters()));
 }
Beispiel #14
0
        internal virtual void WriteSummary(NukeBuild build)
        {
            if (SevereMessages.Count > 0)
            {
                WriteNormal();
                WriteSevereMessages();
            }

            WriteNormal();
            WriteSummaryTable(build);
            WriteNormal();

            if (build.IsSuccessful)
            {
                WriteSuccessfulBuild();
            }
            else
            {
                WriteFailedBuild();
            }

            bool HasHighUsage()
            =>     // global tool
            build.GetType().GetInterfaces().Length > 1 ||
            // configuration generation
            build.GetType().GetCustomAttributes <ConfigurationAttributeBase>().Any() ||
            // interface implementations
            NukeBuild.BuildProjectFile == null;

            T TryGetValue <T>(Func <T> func)
            {
                try
                {
                    return(func.Invoke());
                }
                catch
                {
                    return(default);
Beispiel #15
0
        public static string GetParametersText(NukeBuild build)
        {
            var defaultTarget = build.ExecutableTargets.Single(x => x.IsDefault);
            var builder       = new StringBuilder();

            var parameters = InjectionUtility.GetParameterMembers(build.GetType())
                             .Where(x => !x.HasCustomAttribute <UnlistedAttribute>())
                             .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.Instance.GetParameterDescription(parameter)
                    ?.Replace("{default_target}", defaultTarget.Name).Append(".")
                    ?? "<no description>");
                var parameterName = ParameterService.Instance.GetParameterName(parameter).SplitCamelHumpsWithSeparator("-");

                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());
        }
Beispiel #16
0
        protected virtual IEnumerable <TeamCityParameter> GetSecretParameters(NukeBuild build)
        {
            var guids = build.GetType().GetCustomAttributes <TeamCityTokenAttribute>()
                        .ToDictionary(x => x.Name, x => $"credentialsJSON:{Guid.Parse(x.Guid):D}");

            return(ImportSecrets.Select(x =>
                                        new TeamCityConfigurationParameter
            {
                Type = TeamCityParameterType.Password,
                Name = x,
                DefaultValue = guids.GetValueOrDefault(x),
                Display = TeamCityParameterDisplay.Hidden
            }));
        }
Beispiel #17
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());
        }
Beispiel #19
0
        public void Execute(NukeBuild build)
        {
            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();

            string[] GetSubItems(Type type)
            {
                if (type.IsEnum)
                {
                    return(type.GetEnumNames());
                }
                if (type.IsSubclassOf(typeof(Enumeration)))
                {
                    return(type.GetFields(ReflectionService.Static).Select(x => x.Name).ToArray());
                }
                return(null);
            }

            foreach (var parameter in InjectionUtility.GetParameterMembers(build.GetType()))
            {
                var parameterName = ParameterService.Instance.GetParameterName(parameter);
                if (completionItems.ContainsKey(parameterName))
                {
                    continue;
                }

                completionItems[parameterName] = GetSubItems(parameter.GetFieldOrPropertyType())?.OrderBy(x => x).ToArray();
            }

            SerializationTasks.YamlSerializeToFile(completionItems, Constants.GetCompletionFile(NukeBuild.RootDirectory));

            if (EnvironmentInfo.ParameterSwitch(Constants.CompletionParameterName))
            {
                Environment.Exit(exitCode: 0);
            }
        }
Beispiel #20
0
        public static void SetValue(NukeBuild build, MemberInfo member, object value)
        {
            if (member is FieldInfo field)
            {
                field.SetValue(build, value);
            }
            else if (member is PropertyInfo property)
            {
                var backingField = build.GetType().DescendantsAndSelf(x => x.GetTypeInfo().BaseType)
                                   .SelectMany(x => x.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance))
                                   .SingleOrDefault(x => x.Name.StartsWith($"<{member.Name}>"));

                if (backingField != null)
                {
                    backingField.SetValue(build, value);
                }
                else
                {
                    ControlFlow.Assert(property.SetMethod != null, $"Property '{member.Name}' is not settable.");
                    property.SetValue(build, value);
                }
            }
        }
Beispiel #21
0
 private Dictionary <string, string> GetSecrets(NukeBuild build)
 {
     return(build.GetType().GetCustomAttributes <AppVeyorSecretAttribute>()
            .Where(x => Secrets == null || Secrets.Contains(x.Parameter))
            .ToDictionary(x => x.Parameter, x => x.Value));
 }
Beispiel #22
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);
        }
Beispiel #23
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());
        }
        public override ConfigurationEntity GetConfiguration(
            NukeBuild build,
            IReadOnlyCollection <ExecutableTarget> relevantTargets
            )
        {
            var steps = new List <GitHubActionsStep> {
                new CheckoutStep("Checkout"),
                // new SetupDotNetStep("Install .NET Core Sdk"),
            };


            var globalToolStep = new RunStep("Install Nuke Global Tool")
            {
                Run = "dotnet tool install -g Nuke.GlobalTool"
            };
            var dotnetTools = Path.Combine(NukeBuild.RootDirectory, ".config/dotnet-tools.json");
            var localTool   = false;

            if (File.Exists(dotnetTools))
            {
                steps.Add(new RunStep("dotnet tool restore")
                {
                    Run = "dotnet tool restore"
                });
                if (!File.ReadAllText(dotnetTools).Contains("\"nuke.globaltool\": {"))
                {
                    steps.Add(globalToolStep);
                }
                else
                {
                    localTool = true;
                }
            }
            else
            {
                steps.Add(globalToolStep);
            }

            var stepParameters = GetParameters(build).Select(z => $"--{z.Name.ToLowerInvariant()} '${{{{ env.{z.Name.ToUpperInvariant()} }}}}'")
                                 .ToArray()
                                 .JoinSpace();

            var lookupTable = new LookupTable <ExecutableTarget, ExecutableTarget[]>();

            foreach (var(execute, targets) in relevantTargets
                     .Select(x => (ExecutableTarget: x, Targets: GetInvokedTargets(x, relevantTargets).ToArray()))
                     .ForEachLazy(x => lookupTable.Add(x.ExecutableTarget, x.Targets.ToArray()))
                     )
            {
                steps.Add(new RunStep(execute.Name.Humanize(LetterCasing.Title))
                {
                    Run = $"{( localTool ? "dotnet nuke" : "nuke" )} {targets.Select(z => z.Name).JoinSpace()} --skip {stepParameters}".TrimEnd()
                });
            }

            var config = new RocketSurgeonGitHubActionsConfiguration()
            {
                Name             = _name,
                DetailedTriggers = GetTriggers().ToList(),
                Jobs             = new List <RocketSurgeonsGithubActionsJob> {
                    new RocketSurgeonsGithubActionsJob("Build")
                    {
                        Steps  = steps,
                        Images = _images,
                    }
                }
            };

            if (Enhancements?.Any() == true)
            {
                foreach (var method in Enhancements.Join(build.GetType().GetMethods(), z => z, z => z.Name, (_, e) => e))
                {
                    config = method.IsStatic
                        ? method.Invoke(null, new object[] { config }) as RocketSurgeonGitHubActionsConfiguration ?? config
                        : method.Invoke(build, new object[] { config }) as RocketSurgeonGitHubActionsConfiguration ?? config;
                }
            }

            return(config);
        }
 protected static IEnumerable <IConfigurationGenerator> GetGenerators(NukeBuild build)
 {
     return(build.GetType().GetCustomAttributes <ConfigurationAttributeBase>());
 }