Skip to content

Commit 9885956

Browse files
author
Matthias Koch
committed
Reimplement backwards-compatibility
1 parent aebef03 commit 9885956

9 files changed

Lines changed: 134 additions & 23 deletions

File tree

source/Nuke.Common/Constants.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ internal static class Constants
2727
"GitLab"
2828
};
2929

30+
internal const string NukeFileName = NukeDirectoryName;
3031
internal const string NukeDirectoryName = ".nuke";
3132
internal const string NukeCommonPackageId = nameof(Nuke) + "." + nameof(Common);
3233
internal const string BuildSchemaFileName = "build.schema.json";
@@ -50,9 +51,13 @@ internal static AbsolutePath TryGetRootDirectoryFrom(string startDirectory, bool
5051
return (AbsolutePath) FileSystemTasks.FindParentDirectory(
5152
startDirectory,
5253
predicate: x =>
53-
includeLegacy
54-
? x.GetFileSystemInfos(NukeDirectoryName).Any()
55-
: x.GetDirectories(NukeDirectoryName).Any());
54+
x.GetDirectories(NukeDirectoryName).Any() ||
55+
includeLegacy && x.GetFiles(NukeFileName).Any());
56+
}
57+
58+
internal static bool IsLegacy(AbsolutePath rootDirectory)
59+
{
60+
return File.Exists(rootDirectory / NukeFileName);
5661
}
5762

5863
internal static AbsolutePath GetNukeDirectory(AbsolutePath rootDirectory)
@@ -62,7 +67,9 @@ internal static AbsolutePath GetNukeDirectory(AbsolutePath rootDirectory)
6267

6368
internal static AbsolutePath GetTemporaryDirectory(AbsolutePath rootDirectory)
6469
{
65-
return GetNukeDirectory(rootDirectory) / "temp";
70+
return !IsLegacy(rootDirectory)
71+
? GetNukeDirectory(rootDirectory) / "temp"
72+
: rootDirectory / ".tmp";
6673
}
6774

6875
internal static AbsolutePath GetCompletionFile(AbsolutePath rootDirectory)

source/Nuke.Common/Execution/ArgumentsFromParametersFileAttribute.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public class ArgumentsFromParametersFileAttribute : BuildExtensionAttributeBase,
2525

2626
public void OnBuildCreated(NukeBuild build, IReadOnlyCollection<ExecutableTarget> executableTargets)
2727
{
28+
if (!Directory.Exists(Constants.GetNukeDirectory(NukeBuild.RootDirectory)))
29+
return;
30+
2831
var parameterMembers = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: true);
2932
var passwords = new Dictionary<string, byte[]>();
3033

source/Nuke.Common/Execution/HandleShellCompletionAttribute.cs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Linq;
8+
using Nuke.Common.IO;
9+
using Nuke.Common.ValueInjection;
810
using static Nuke.Common.Constants;
911

1012
namespace Nuke.Common.Execution
@@ -13,11 +15,40 @@ internal class HandleShellCompletionAttribute : BuildExtensionAttributeBase, IOn
1315
{
1416
public void OnBuildCreated(NukeBuild build, IReadOnlyCollection<ExecutableTarget> executableTargets)
1517
{
16-
SchemaUtility.WriteBuildSchemaFile(build);
17-
SchemaUtility.WriteDefaultParametersFile();
18+
if (IsLegacy(NukeBuild.RootDirectory))
19+
{
20+
WriteCompletionFile(build);
21+
}
22+
else
23+
{
24+
SchemaUtility.WriteBuildSchemaFile(build);
25+
SchemaUtility.WriteDefaultParametersFile();
26+
}
1827

1928
if (EnvironmentInfo.GetParameter<bool>(CompletionParameterName))
2029
Environment.Exit(exitCode: 0);
2130
}
31+
32+
private static void WriteCompletionFile(NukeBuild build)
33+
{
34+
var completionItems = new SortedDictionary<string, string[]>();
35+
36+
var targets = build.ExecutableTargets.OrderBy(x => x.Name).ToList();
37+
completionItems[InvokedTargetsParameterName] = targets.Where(x => x.Listed).Select(x => x.Name).ToArray();
38+
completionItems[SkippedTargetsParameterName] = targets.Select(x => x.Name).ToArray();
39+
40+
var parameters = ValueInjectionUtility.GetParameterMembers(build.GetType(), includeUnlisted: false);
41+
foreach (var parameter in parameters)
42+
{
43+
var parameterName = ParameterService.GetParameterMemberName(parameter);
44+
if (completionItems.ContainsKey(parameterName))
45+
continue;
46+
47+
var subItems = ParameterService.GetParameterValueSet(parameter, build)?.Select(x => x.Text);
48+
completionItems[parameterName] = subItems?.ToArray();
49+
}
50+
51+
SerializationTasks.YamlSerializeToFile(completionItems, GetCompletionFile(NukeBuild.RootDirectory));
52+
}
2253
}
2354
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2021 Maintainers of NUKE.
2+
// Distributed under the MIT License.
3+
// https://github.com/nuke-build/nuke/blob/master/LICENSE
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.IO;
8+
using System.Linq;
9+
using Nuke.Common.Utilities;
10+
using static Nuke.Common.Constants;
11+
12+
namespace Nuke.Common.Execution
13+
{
14+
internal class UpdateNotificationAttribute : BuildExtensionAttributeBase,
15+
IOnBuildCreated,
16+
IOnBuildFinished
17+
{
18+
public void OnBuildCreated(NukeBuild build, IReadOnlyCollection<ExecutableTarget> executableTargets)
19+
{
20+
if (NukeBuild.IsLocalBuild && ShouldNotify)
21+
{
22+
Notify();
23+
Logger.Info("Press any key to continue...");
24+
Console.ReadKey();
25+
}
26+
}
27+
28+
public void OnBuildFinished(NukeBuild build)
29+
{
30+
if (NukeBuild.IsServerBuild && ShouldNotify)
31+
Notify();
32+
}
33+
34+
private bool ShouldNotify => !Directory.Exists(GetNukeDirectory(NukeBuild.RootDirectory));
35+
36+
private static void Notify()
37+
{
38+
Logger.Warn(
39+
new[]
40+
{
41+
"--- UPDATE RECOMMENDED FROM 5.1.0 ---",
42+
"1. Update your global tool",
43+
" dotnet tool update Nuke.GlobalTool -g",
44+
"2. Update your build",
45+
" nuke :update",
46+
"3. Confirm on update for configuration file and build scripts",
47+
" (Others are be optional)",
48+
string.Empty
49+
}.JoinNewLine());
50+
}
51+
}
52+
}

source/Nuke.Common/NukeBuild.Statics.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ static NukeBuild()
2222
RootDirectory = GetRootDirectory();
2323
TemporaryDirectory = GetTemporaryDirectory(RootDirectory);
2424
FileSystemTasks.EnsureExistingDirectory(TemporaryDirectory);
25+
2526
BuildAssemblyDirectory = GetBuildAssemblyDirectory();
2627
BuildProjectFile = GetBuildProjectFile(BuildAssemblyDirectory);
2728
BuildProjectDirectory = BuildProjectFile?.Parent;
@@ -100,8 +101,8 @@ private static AbsolutePath GetRootDirectory()
100101
return TryGetRootDirectoryFrom(EnvironmentInfo.WorkingDirectory)
101102
.NotNull(new[]
102103
{
103-
$"Could not locate '{NukeDirectoryName}' directory while walking up from '{EnvironmentInfo.WorkingDirectory}'.",
104-
"Either create the directory to mark the root directory, or use the --root parameter to use the working directory."
104+
$"Could not locate '{NukeDirectoryName}' directory/file while walking up from '{EnvironmentInfo.WorkingDirectory}'.",
105+
"Either create a directory/file to mark the root directory, or add '--root [path]' to the invocation."
105106
}.JoinNewLine());
106107
}
107108

source/Nuke.Common/NukeBuild.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ namespace Nuke.Common
5959
[HandleVisualStudioDebugging]
6060
[InjectNonParameterValues(Priority = -100)]
6161
// After finish
62+
[UpdateNotification]
6263
[SerializeBuildServerState]
6364
public abstract partial class NukeBuild : INukeBuild
6465
{

source/Nuke.Common/ProjectModel/SolutionAttribute.cs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// https://github.com/nuke-build/nuke/blob/master/LICENSE
44

55
using System;
6+
using System.IO;
67
using System.Linq;
78
using System.Reflection;
89
using JetBrains.Annotations;
@@ -49,25 +50,37 @@ public SolutionAttribute(string relativePath)
4950

5051
public override object GetValue(MemberInfo member, object instance)
5152
{
53+
var solutionFile = TryGetSolutionFileFromNukeFile() ??
54+
GetSolutionFileFromParametersFile(member);
5255
var deserializer = typeof(SolutionSerializer).GetMethod(nameof(SolutionSerializer.DeserializeFromFile)).NotNull()
5356
.MakeGenericMethod(member.GetMemberType());
54-
return deserializer.Invoke(obj: null, new object[] { GetSolutionFile(member) });
57+
return deserializer.Invoke(obj: null, new object[] { solutionFile });
5558
}
5659

5760
// TODO: allow wildcard matching? [Solution("nuke-*.sln")] -- no globbing?
5861
// TODO: for just [Solution] without parameter being passed, do wildcard search?
59-
private string GetSolutionFile(MemberInfo member)
62+
private string GetSolutionFileFromParametersFile(MemberInfo member)
6063
{
61-
if (_relativePath != null)
62-
return PathConstruction.Combine(NukeBuild.RootDirectory, _relativePath);
64+
return _relativePath != null
65+
? PathConstruction.Combine(NukeBuild.RootDirectory, _relativePath)
66+
: EnvironmentInfo.GetParameter<AbsolutePath>(member).NotNull($"No solution file defined for '{member.Name}'.");
67+
}
68+
69+
private string TryGetSolutionFileFromNukeFile()
70+
{
71+
var nukeFile = Path.Combine(NukeBuild.RootDirectory, Constants.NukeFileName);
72+
if (!File.Exists(nukeFile))
73+
return null;
74+
75+
var solutionFileRelative = File.ReadAllLines(nukeFile).ElementAtOrDefault(0);
76+
ControlFlow.Assert(solutionFileRelative != null && !solutionFileRelative.Contains(value: '\\'),
77+
$"First line of {Constants.NukeFileName} must provide solution path using UNIX separators");
78+
79+
var solutionFile = Path.GetFullPath(Path.Combine(NukeBuild.RootDirectory, solutionFileRelative));
80+
ControlFlow.Assert(File.Exists(solutionFile),
81+
$"Solution file '{solutionFile}' provided via {Constants.NukeFileName} does not exist.");
6382

64-
var solutionFile = EnvironmentInfo.GetParameter<AbsolutePath>(member);
65-
return solutionFile.NotNull(
66-
new[]
67-
{
68-
$"No solution file defined for '{member.Name}'.",
69-
$"Invoke: nuke --save-profile --{ParameterService.GetParameterDashedName(member)} <value>"
70-
}.JoinNewLine());
83+
return (AbsolutePath) solutionFile;
7184
}
7285
}
7386
}

source/Nuke.GlobalTool/Program.Complete.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// https://github.com/nuke-build/nuke/blob/master/LICENSE
44

55
using System;
6+
using System.Collections.Generic;
67
using System.IO;
78
using System.Linq;
89
using JetBrains.Annotations;
@@ -31,15 +32,17 @@ public static int Complete(string[] args, [CanBeNull] AbsolutePath rootDirectory
3132
words = words.Substring(CommandName.Length).TrimStart();
3233

3334
var buildSchemaFile = GetBuildSchemaFile(rootDirectory);
34-
if (!File.Exists(buildSchemaFile))
35+
var completionFile = GetCompletionFile(rootDirectory);
36+
if (!File.Exists(buildSchemaFile) && !File.Exists(completionFile))
3537
{
3638
Build(buildScript.NotNull(), $"--{CompletionParameterName}");
3739
return 1;
3840
}
3941

4042
var position = EnvironmentInfo.GetParameter<int?>("position");
41-
var profileNames = GetProfileNames(rootDirectory);
42-
var completionItems = SchemaUtility.GetCompletionItems(buildSchemaFile, profileNames);
43+
var completionItems = IsLegacy(rootDirectory)
44+
? SerializationTasks.YamlDeserializeFromFile<Dictionary<string, string[]>>(completionFile)
45+
: SchemaUtility.GetCompletionItems(buildSchemaFile, GetProfileNames(rootDirectory));
4346
foreach (var item in CompletionUtility.GetRelevantCompletionItems(words, completionItems))
4447
Console.WriteLine(item);
4548

source/Nuke.GlobalTool/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private static int Handle(string[] args, [CanBeNull] AbsolutePath rootDirectory,
8989
if (rootDirectory == null || buildScript == null)
9090
{
9191
var missingItem = rootDirectory == null
92-
? $"{Constants.NukeDirectoryName} directory"
92+
? $"{Constants.NukeDirectoryName} directory/file"
9393
: "build.ps1/sh files";
9494

9595
return UserConfirms($"Could not find {missingItem}. Do you want to setup a build?")

0 commit comments

Comments
 (0)