diff --git a/.editorconfig b/.editorconfig
index 46a2f0f..776fb87 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -9,6 +9,26 @@ insert_final_newline = true
tab_width = 2
trim_trailing_whitespace = true
+[*.cs]
+csharp_indent_case_contents_when_block = false
+csharp_indent_labels = no_change
+csharp_new_line_before_open_brace = none
+csharp_prefer_braces = false
+csharp_space_after_cast = true
+csharp_space_before_colon_in_inheritance_clause = false
+csharp_style_expression_bodied_constructors = true
+csharp_style_expression_bodied_local_functions = true
+csharp_style_expression_bodied_methods = true
+csharp_style_expression_bodied_operators = true
+csharp_style_namespace_declarations = file_scoped
+csharp_style_var_elsewhere = true
+csharp_style_var_for_built_in_types = true
+csharp_style_var_when_type_is_apparent = true
+csharp_using_directive_placement = inside_namespace
+dotnet_diagnostic.CS8524.severity = silent
+dotnet_sort_system_directives_first = false
+dotnet_style_namespace_match_folder = false
+
[*.md]
trim_trailing_whitespace = false
diff --git a/.gitattributes b/.gitattributes
index c510df3..c16a191 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,21 +1,30 @@
* text=auto
.* text
+*.cjs text
*.config text
*.cs text diff=csharp
*.csproj text
*.css text diff=css
+*.esproj text
*.html text diff=html
*.http text
*.ini text
-*.iss text
+*.js text
*.json text
*.md text diff=markdown
+*.mjs text
+*.php text diff=php
*.ps1 text
+*.psd1 text
+*.razor text
+*.scss text diff=css
*.slnx text
*.sql text
*.svg text
+*.ts text
*.txt text
+*.webmanifest text
*.xml text
*.yaml text
*.yml text
diff --git a/.gitignore b/.gitignore
index b4ce5b1..03555ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,5 +2,5 @@
/.idea/
/.vs/
/bin/
-/src/obj/
+/*/obj/
/var/
diff --git a/.runsettings b/.runsettings
new file mode 100644
index 0000000..5aaedf1
--- /dev/null
+++ b/.runsettings
@@ -0,0 +1,5 @@
+
+
+ var/TestResults
+
+
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index b408c54..e2d0e78 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -1,5 +1,6 @@
{
"recommendations": [
+ "ms-dotnettools.csdevkit",
"ms-vscode.powershell"
]
}
diff --git a/Invoke.ps1 b/Invoke.ps1
index e96d6ee..6be28b1 100755
--- a/Invoke.ps1
+++ b/Invoke.ps1
@@ -5,7 +5,10 @@ param (
param ($commandName, $parameterName, $wordToComplete)
(Get-Item "$PSScriptRoot/tool/$wordToComplete*.ps1").BaseName
})]
- [string] $Command = "Default"
+ [string] $Command = "Default",
+
+ [Parameter()]
+ [switch] $Release
)
$ErrorActionPreference = "Stop"
diff --git a/SetupAnt.psd1 b/SetupAnt.psd1
index 528d918..8ce783d 100644
--- a/SetupAnt.psd1
+++ b/SetupAnt.psd1
@@ -2,7 +2,7 @@
DefaultCommandPrefix = "Ant"
ModuleVersion = "5.1.0"
PowerShellVersion = "7.4"
- RootModule = "src/Main.psm1"
+ RootModule = "bin/Belin.SetupAnt.dll"
Author = "Cédric Belin "
CompanyName = "Cedric-Belin.fr"
@@ -11,10 +11,10 @@
GUID = "30b52520-21cd-44c4-aa11-b1f0dc085686"
AliasesToExport = @()
- CmdletsToExport = @()
+ FunctionsToExport = @()
VariablesToExport = @()
- FunctionsToExport = @(
+ CmdletsToExport = @(
"Find-Release"
"Get-Release"
"Install-Release"
@@ -22,11 +22,6 @@
"Test-Release"
)
- NestedModules = @(
- "src/Release.psm1"
- "src/Setup.psm1"
- )
-
PrivateData = @{
PSData = @{
LicenseUri = "https://github.com/cedx/setup-ant/blob/main/License.md"
diff --git a/SetupAnt.slnx b/SetupAnt.slnx
index 800db64..e1985c4 100644
--- a/SetupAnt.slnx
+++ b/SetupAnt.slnx
@@ -3,6 +3,7 @@
+
@@ -21,24 +22,25 @@
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
diff --git a/Start.ps1 b/Start.ps1
index d215dad..485e5a3 100755
--- a/Start.ps1
+++ b/Start.ps1
@@ -1,11 +1,11 @@
#!/usr/bin/env pwsh
-using module ./src/Release.psm1
-using module ./src/Setup.psm1
+using assembly ./bin/Belin.SetupAnt.dll
+using namespace Belin.SetupAnt
$ErrorActionPreference = "Stop"
$PSNativeCommandUseErrorActionPreference = $true
Set-StrictMode -Version Latest
-if (-not (Test-Path Env:SETUP_ANT_VERSION)) { $Env:SETUP_ANT_VERSION = "latest" }
+if (-not (Test-Path Env:SETUP_ANT_VERSION)) { $Env:SETUP_ANT_VERSION = "Latest" }
$release = [Release]::Find($Env:SETUP_ANT_VERSION)
if (-not $release) { throw "No release matching the version constraint." }
diff --git a/src/Cmdlets/Find-Release.cs b/src/Cmdlets/Find-Release.cs
new file mode 100644
index 0000000..90d264a
--- /dev/null
+++ b/src/Cmdlets/Find-Release.cs
@@ -0,0 +1,20 @@
+namespace Belin.SetupAnt.Cmdlets;
+
+///
+/// Finds a release that matches the specified version constraint.
+///
+[Cmdlet(VerbsCommon.Find, "Release")]
+[OutputType(typeof(Release))]
+public class FindReleaseCommand: Cmdlet {
+
+ ///
+ /// The version constraint.
+ ///
+ [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)]
+ public required string Constraint { get; set; }
+
+ ///
+ /// Performs execution of this command.
+ ///
+ protected override void ProcessRecord() => WriteObject(Release.Find(Constraint));
+}
diff --git a/src/Cmdlets/Get-Release.cs b/src/Cmdlets/Get-Release.cs
new file mode 100644
index 0000000..33f3646
--- /dev/null
+++ b/src/Cmdlets/Get-Release.cs
@@ -0,0 +1,24 @@
+namespace Belin.SetupAnt.Cmdlets;
+
+using System.Data;
+using System.Text.RegularExpressions;
+
+///
+/// Gets the release corresponding to the specified version.
+///
+[Cmdlet(VerbsCommon.Get, "Release")]
+[OutputType(typeof(Release))]
+public class GetReleaseCommand: Cmdlet {
+
+ ///
+ /// The version number. Use `*` or `Latest` to get the latest release.
+ ///
+ [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)]
+ public required string Version { get; set; }
+
+ ///
+ /// Performs execution of this command.
+ ///
+ protected override void ProcessRecord() =>
+ WriteObject(Release.LatestReleasePattern().IsMatch(Version) ? Release.Latest : Release.Get(Version));
+}
diff --git a/src/Cmdlets/Install-Release.cs b/src/Cmdlets/Install-Release.cs
new file mode 100644
index 0000000..ca0f9f2
--- /dev/null
+++ b/src/Cmdlets/Install-Release.cs
@@ -0,0 +1,35 @@
+namespace Belin.SetupAnt.Cmdlets;
+
+///
+/// Installs Apache Ant, after downloading it.
+///
+[Cmdlet(VerbsLifecycle.Install, "Release")]
+[OutputType(typeof(string))]
+public class InstallReleaseCommand: PSCmdlet {
+
+ ///
+ /// The instance of the release to be installed.
+ ///
+ [Parameter(Mandatory = true, ParameterSetName = "InputObject", ValueFromPipeline = true)]
+ public required Release InputObject { get; set; }
+
+ ///
+ /// Value indicating whether to fetch the Ant optional tasks.
+ ///
+ [Parameter]
+ public SwitchParameter OptionalTasks { get; set; }
+
+ ///
+ /// The version number of the release to be installed.
+ ///
+ [Parameter(Mandatory = true, ParameterSetName = "Version", Position = 0, ValueFromPipeline = true)]
+ public required Version Version { get; set; }
+
+ ///
+ /// Performs execution of this command.
+ ///
+ protected override void ProcessRecord() {
+ var release = ParameterSetName == "InputObject" ? InputObject : new Release(Version);
+ WriteObject(new Setup(release).Install(OptionalTasks).GetAwaiter().GetResult());
+ }
+}
diff --git a/src/Cmdlets/New-Release.cs b/src/Cmdlets/New-Release.cs
new file mode 100644
index 0000000..b9d9783
--- /dev/null
+++ b/src/Cmdlets/New-Release.cs
@@ -0,0 +1,20 @@
+namespace Belin.SetupAnt.Cmdlets;
+
+///
+/// Creates a new release.
+///
+[Cmdlet(VerbsCommon.New, "Release")]
+[OutputType(typeof(Release))]
+public class NewReleaseCommand: Cmdlet {
+
+ ///
+ /// The version number.
+ ///
+ [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true)]
+ public required Version Version { get; set; }
+
+ ///
+ /// Performs execution of this command.
+ ///
+ protected override void ProcessRecord() => WriteObject(new Release(Version));
+}
diff --git a/src/Cmdlets/Test-Release.cs b/src/Cmdlets/Test-Release.cs
new file mode 100644
index 0000000..0b98152
--- /dev/null
+++ b/src/Cmdlets/Test-Release.cs
@@ -0,0 +1,29 @@
+namespace Belin.SetupAnt.Cmdlets;
+
+///
+/// Gets a value indicating whether a release with the specified version exists.
+///
+[Cmdlet(VerbsDiagnostic.Test, "Release", DefaultParameterSetName = "Version")]
+[OutputType(typeof(bool))]
+public class TestReleaseCommand: PSCmdlet {
+
+ ///
+ /// The version number of the release to be tested.
+ ///
+ [Parameter(Mandatory = true, ParameterSetName = "InputObject", ValueFromPipeline = true)]
+ public required Release InputObject { get; set; }
+
+ ///
+ /// The version number of the release to be tested.
+ ///
+ [Parameter(Mandatory = true, ParameterSetName = "Version", Position = 0, ValueFromPipeline = true)]
+ public required Version Version { get; set; }
+
+ ///
+ /// Performs execution of this command.
+ ///
+ protected override void ProcessRecord() {
+ var release = ParameterSetName == "InputObject" ? InputObject : new Release(Version);
+ WriteObject(release.Exists);
+ }
+}
diff --git a/src/Data.psd1 b/src/Data.psd1
deleted file mode 100644
index bb8e9a0..0000000
--- a/src/Data.psd1
+++ /dev/null
@@ -1,52 +0,0 @@
-@{
- Releases = @(
- "1.10.15"
- "1.10.14"
- "1.10.13"
- "1.10.12"
- "1.10.11"
- "1.10.10"
- "1.10.9"
- "1.10.8"
- "1.10.7"
- "1.10.6"
- "1.10.5"
- "1.10.4"
- "1.10.3"
- "1.10.2"
- "1.10.1"
- "1.10.0"
- "1.9.16"
- "1.9.15"
- "1.9.14"
- "1.9.13"
- "1.9.12"
- "1.9.11"
- "1.9.10"
- "1.9.9"
- "1.9.8"
- "1.9.7"
- "1.9.6"
- "1.9.5"
- "1.9.4"
- "1.9.3"
- "1.9.2"
- "1.9.1"
- "1.9.0"
- "1.8.4"
- "1.8.3"
- "1.8.2"
- "1.8.1"
- "1.8.0"
- "1.7.1"
- "1.7.0"
- "1.6.5"
- "1.6.4"
- "1.6.3"
- "1.6.2"
- "1.6.1"
- "1.6.0"
- "1.5.4"
- "1.5.2"
- )
-}
diff --git a/src/Main.psm1 b/src/Main.psm1
deleted file mode 100644
index e70392c..0000000
--- a/src/Main.psm1
+++ /dev/null
@@ -1,140 +0,0 @@
-using namespace System.Diagnostics.CodeAnalysis
-using module ./Release.psm1
-using module ./Setup.psm1
-
-<#
-.SYNOPSIS
- Finds a release that matches the specified version constraint.
-.PARAMETER Constraint
- The version constraint.
-.INPUTS
- A string that contains a version constraint.
-.OUTPUTS
- The release corresponding to the specified constraint, or `$null` if not found.
-#>
-function Find-Release {
- [CmdletBinding()]
- [OutputType([Release])]
- param (
- [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
- [string] $Constraint
- )
-
- process {
- [Release]::Find($Constraint)
- }
-}
-
-<#
-.SYNOPSIS
- Gets the release corresponding to the specified version.
-.PARAMETER Version
- The version number. Use `*` or `Latest` to get the latest release.
-.INPUTS
- A string that contains a version number.
-.OUTPUTS
- The release corresponding to the specified version, or `$null` if not found.
-#>
-function Get-Release {
- [CmdletBinding()]
- [OutputType([Release])]
- param (
- [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
- [string] $Version
- )
-
- process {
- $Version -in "*", "Latest" ? [Release]::Latest() : [Release]::Get($Version)
- }
-}
-
-<#
-.SYNOPSIS
- Installs Apache Ant, after downloading it.
-.PARAMETER Version
- The version number of the release to be installed.
-.PARAMETER InputObject
- The instance of the release to be installed.
-.PARAMETER OptionalTasks
- Value indicating whether to fetch the Ant optional tasks.
-.INPUTS
- [string] A string that contains a version number.
-.INPUTS
- [Release] An instance of the `Release` class to be installed.
-.OUTPUTS
- The path to the installation directory.
-#>
-function Install-Release {
- [CmdletBinding(DefaultParameterSetName = "Version")]
- [OutputType([string])]
- param (
- [Parameter(Mandatory, ParameterSetName = "Version", Position = 0, ValueFromPipeline)]
- [string] $Version,
-
- [Parameter(Mandatory, ParameterSetName = "InputObject", ValueFromPipeline)]
- [Release] $InputObject,
-
- [Parameter()]
- [switch] $OptionalTasks
- )
-
- process {
- $release = $PSCmdlet.ParameterSetName -eq "InputObject" ? $InputObject : [Release]::new($Version)
- [Setup]::new($release).Install($OptionalTasks)
- }
-}
-
-<#
-.SYNOPSIS
- Creates a new release.
-.PARAMETER Version
- The version number.
-.INPUTS
- A string that contains a version number.
-.OUTPUTS
- The newly created release.
-#>
-function New-Release {
- [CmdletBinding()]
- [OutputType([Release])]
- [SuppressMessage("PSUseShouldProcessForStateChangingFunctions", "")]
- param (
- [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
- [string] $Version
- )
-
- process {
- [Release]::new($Version)
- }
-}
-
-<#
-.SYNOPSIS
- Gets a value indicating whether a release with the specified version exists.
-.PARAMETER Version
- The version number of the release to be tested.
-.PARAMETER InputObject
- The instance of the release to be tested.
-.INPUTS
- [string] A string that contains a version number.
-.INPUTS
- [Release] An instance of the `Release` class to be tested.
-.OUTPUTS
- `$true` if a release with the specified version exists, otherwise `$false`.
-#>
-function Test-Release {
- [CmdletBinding(DefaultParameterSetName = "Version")]
- [OutputType([bool])]
- param (
- [Parameter(Mandatory, ParameterSetName = "Version", Position = 0, ValueFromPipeline)]
- [string] $Version,
-
- [Parameter(Mandatory, ParameterSetName = "InputObject", ValueFromPipeline)]
- [Release] $InputObject
- )
-
- process {
- $release = $PSCmdlet.ParameterSetName -eq "InputObject" ? $InputObject : [Release]::new($Version)
- $release.Exists()
- }
-}
diff --git a/src/Release.Data.cs b/src/Release.Data.cs
new file mode 100644
index 0000000..cf28678
--- /dev/null
+++ b/src/Release.Data.cs
@@ -0,0 +1,61 @@
+namespace Belin.SetupAnt;
+
+///
+/// Represents an Apache Ant release.
+///
+public partial class Release {
+
+ ///
+ /// The list of all releases.
+ ///
+ private static readonly Release[] data = [
+ new Release("1.10.15"),
+ new Release("1.10.14"),
+ new Release("1.10.13"),
+ new Release("1.10.12"),
+ new Release("1.10.11"),
+ new Release("1.10.10"),
+ new Release("1.10.9"),
+ new Release("1.10.8"),
+ new Release("1.10.7"),
+ new Release("1.10.6"),
+ new Release("1.10.5"),
+ new Release("1.10.4"),
+ new Release("1.10.3"),
+ new Release("1.10.2"),
+ new Release("1.10.1"),
+ new Release("1.10.0"),
+ new Release("1.9.16"),
+ new Release("1.9.15"),
+ new Release("1.9.14"),
+ new Release("1.9.13"),
+ new Release("1.9.12"),
+ new Release("1.9.11"),
+ new Release("1.9.10"),
+ new Release("1.9.9"),
+ new Release("1.9.8"),
+ new Release("1.9.7"),
+ new Release("1.9.6"),
+ new Release("1.9.5"),
+ new Release("1.9.4"),
+ new Release("1.9.3"),
+ new Release("1.9.2"),
+ new Release("1.9.1"),
+ new Release("1.9.0"),
+ new Release("1.8.4"),
+ new Release("1.8.3"),
+ new Release("1.8.2"),
+ new Release("1.8.1"),
+ new Release("1.8.0"),
+ new Release("1.7.1"),
+ new Release("1.7.0"),
+ new Release("1.6.5"),
+ new Release("1.6.4"),
+ new Release("1.6.3"),
+ new Release("1.6.2"),
+ new Release("1.6.1"),
+ new Release("1.6.0"),
+ new Release("1.5.4"),
+ new Release("1.5.2")
+ ];
+}
diff --git a/src/Release.cs b/src/Release.cs
new file mode 100644
index 0000000..94965d9
--- /dev/null
+++ b/src/Release.cs
@@ -0,0 +1,126 @@
+namespace Belin.SetupAnt;
+
+using System.Linq;
+using System.Text.RegularExpressions;
+
+///
+/// Represents an Apache Ant release.
+///
+/// The version number.
+public partial class Release(Version version): IEquatable {
+
+ ///
+ /// The latest release.
+ ///
+ public static Release Latest => data.First();
+
+ ///
+ /// Gets the regular expression used to check if a version number represents the latest release.
+ ///
+ /// The regular expression used to check if a version number represents the latest release.
+ [GeneratedRegex(@"^(\*|latest)$", RegexOptions.IgnoreCase)]
+ internal static partial Regex LatestReleasePattern();
+
+ ///
+ /// Value indicating whether this release exists.
+ ///
+ public bool Exists => data.Any(release => release == this);
+
+ ///
+ /// The download URL.
+ ///
+ public Uri Url {
+ get {
+ var baseUrl = new Uri(this == Latest ? "https://downloads.apache.org/ant/binaries/": "https://archive.apache.org/dist/ant/binaries/");
+ return new(baseUrl, $"apache-ant-{Version}-bin.zip");
+ }
+ }
+
+ ///
+ /// The version number.
+ ///
+ public Version Version => version;
+
+ ///
+ /// Creates a new release.
+ ///
+ /// The version number.
+ public Release(string version): this(Version.Parse(version)) {}
+
+ ///
+ /// Determines whether the two specified objects are equal.
+ ///
+ /// The first object.
+ /// The second object.
+ /// if object1 equals object2, otherwise .
+ public static bool operator ==(Release? object1, Release? object2) =>
+ object1 is null ? object2 is null : ReferenceEquals(object1, object2) || object1.Equals(object2);
+
+ ///
+ /// Determines whether the two specified objects are not equal.
+ ///
+ /// The first object.
+ /// The second object.
+ /// if object1 does not equal object2, otherwise .
+ public static bool operator !=(Release? object1, Release? object2) => !(object1 == object2);
+
+ ///
+ /// Finds a release that matches the specified version constraint.
+ ///
+ /// The version constraint.
+ /// The release corresponding to the specified constraint, or if not found.
+ /// The version constraint is invalid.
+ public static Release? Find(string constraint) {
+ var operatorMatch = Regex.Match(constraint, @"^([^\d]+)\d");
+ var (op, version) = true switch {
+ true when LatestReleasePattern().IsMatch(constraint) => ("=", Latest.Version.ToString()),
+ true when operatorMatch.Success => (operatorMatch.Groups[1].Value, Regex.Replace(constraint, @"^[^\d]+", "")),
+ true when Regex.IsMatch(constraint, @"^\d") => (">=", constraint),
+ _ => throw new FormatException("The version constraint is invalid.")
+ };
+
+ var semver = SemanticVersion.Parse(version);
+ return data.FirstOrDefault(op switch {
+ ">" => release => new SemanticVersion(release.Version) > semver,
+ ">=" => release => new SemanticVersion(release.Version) >= semver,
+ "=" => release => new SemanticVersion(release.Version) == semver,
+ "<=" => release => new SemanticVersion(release.Version) <= semver,
+ "<" => release => new SemanticVersion(release.Version) < semver,
+ _ => throw new FormatException("The version constraint is invalid.")
+ });
+ }
+
+ ///
+ /// Gets the release corresponding to the specified version.
+ ///
+ /// The version number of a release.
+ /// The release corresponding to the specified version, or if not found.
+ public static Release? Get(string version) => Get(Version.Parse(version));
+
+ ///
+ /// Gets the release corresponding to the specified version.
+ ///
+ /// The version number of a release.
+ /// The release corresponding to the specified version, or if not found.
+ public static Release? Get(Version version) => data.SingleOrDefault(release => release.Version == version);
+
+ ///
+ /// Determines whether the specified object is equal to this object.
+ ///
+ /// An object to compare with this object.
+ /// if the specified object is equal to this object, otherwise .
+ public override bool Equals(object? other) => Equals(other as Release);
+
+ ///
+ /// Determines whether the specified object is equal to this object.
+ ///
+ /// An object to compare with this object.
+ /// if the specified object is equal to this object, otherwise .
+ public bool Equals(Release? other) => other is not null && Version == other.Version;
+
+ ///
+ /// Gets the hash code for this object.
+ ///
+ /// The hash code for this object.
+ public override int GetHashCode() => HashCode.Combine(Version);
+}
diff --git a/src/Release.psm1 b/src/Release.psm1
deleted file mode 100644
index 0e9a265..0000000
--- a/src/Release.psm1
+++ /dev/null
@@ -1,107 +0,0 @@
-<#
-.SYNOPSIS
- Represents an Apache Ant release.
-#>
-class Release {
-
- <#
- .SYNOPSIS
- The list of all releases.
- #>
- hidden static [Release[]] $Data
-
- <#
- .SYNOPSIS
- The version number.
- #>
- [ValidateNotNull()]
- [semver] $Version
-
- <#
- .SYNOPSIS
- Creates a new release.
- .PARAMETER Version
- The version number.
- #>
- Release([string] $Version) {
- $this.Version = $Version
- }
-
- <#
- .SYNOPSIS
- Initializes the class.
- #>
- static Release() {
- [Release]::Data = (Import-PowerShellDataFile "$PSScriptRoot/Data.psd1").Releases.ForEach{ [Release] $_ }
- }
-
- <#
- .SYNOPSIS
- Gets a value indicating whether this release exists.
- .OUTPUTS
- `$true` if this release exists, otherwise `$false`.
- #>
- [bool] Exists() {
- return $null -ne [Release]::Get($this.Version)
- }
-
- <#
- .SYNOPSIS
- Gets the download URL.
- .OUTPUTS
- The download URL.
- #>
- [uri] Url() {
- return "https://archive.apache.org/dist/ant/binaries/apache-ant-$($this.Version)-bin.zip"
- }
-
- <#
- .SYNOPSIS
- Finds a release that matches the specified version constraint.
- .PARAMETER Constraint
- The version constraint.
- .OUTPUTS
- The release corresponding to the specified constraint, or `$null` if not found.
- #>
- static [Release] Find([string] $Constraint) {
- $operator, $semver = switch -Regex ($Constraint) {
- "^(\*|latest)$" { "=", [Release]::Latest().Version; break }
- "^([^\d]+)\d" { $Matches[1], [semver] ($Constraint -replace "^[^\d]+", ""); break }
- "^\d" { ">=", [semver] $Constraint; break }
- default { throw [FormatException] "The version constraint is invalid." }
- }
-
- $predicate = switch ($operator) {
- ">=" { { $_.Version -ge $semver }; break }
- ">" { { $_.Version -gt $semver }; break }
- "<=" { { $_.Version -le $semver }; break }
- "<" { { $_.Version -lt $semver }; break }
- "=" { { $_.Version -eq $semver }; break }
- default { throw [FormatException] "The version constraint is invalid." }
- }
-
- return [Release]::Data.Where($predicate)[0]
- }
-
- <#
- .SYNOPSIS
- Gets the release corresponding to the specified version.
- .PARAMETER Version
- The version number of a release.
- .OUTPUTS
- The release corresponding to the specified version, or `$null` if not found.
- #>
- static [Release] Get([string] $Version) {
- return [Release]::Data.Where({ $_.Version -eq $Version }, "First")[0]
- }
-
- <#
- .SYNOPSIS
- Gets the latest release.
- .OUTPUTS
- The latest release, or `$null` if not found.
- #>
- static [Release] Latest() {
- return [Release]::Data[0]
- }
-}
diff --git a/src/Setup.cs b/src/Setup.cs
new file mode 100644
index 0000000..2bf22f0
--- /dev/null
+++ b/src/Setup.cs
@@ -0,0 +1,75 @@
+namespace Belin.SetupAnt;
+
+using System.Diagnostics;
+using System.IO;
+using System.IO.Compression;
+using System.Threading;
+
+///
+/// Manages the download and installation of Apache Ant.
+///
+/// The release to download and install.
+public class Setup(Release release) {
+
+ ///
+ /// Downloads and extracts the ZIP archive of Apache Ant.
+ ///
+ /// Value indicating whether to fetch the Ant optional tasks.
+ /// The token to cancel the operation.
+ /// The path to the extracted directory.
+ public async Task Download(bool optionalTasks = false, CancellationToken cancellationToken = default) {
+ using var httpClient = new HttpClient();
+ var version = GetType().Assembly.GetName().Version!;
+ httpClient.DefaultRequestHeaders.Add("User-Agent", $".NET/{Environment.Version.ToString(3)} | SetupAnt/{version.ToString(3)}");
+
+ var bytes = await httpClient.GetByteArrayAsync(release.Url, cancellationToken);
+ var file = Path.GetTempFileName();
+ await File.WriteAllBytesAsync(file, bytes, cancellationToken);
+
+ var directory = Path.Join(Path.GetTempPath(), Guid.NewGuid().ToString());
+ // TODO (.NET 10) await ZipFile.ExtractToDirectoryAsync(file, directory, cancellationToken);
+ ZipFile.ExtractToDirectory(file, directory);
+
+ var antHome = Path.Join(directory, Path.GetFileName(Directory.EnumerateDirectories(directory).Single()));
+ if (optionalTasks) await FetchOptionalTasks(antHome);
+ return antHome;
+ }
+
+ ///
+ /// Installs Apache Ant, after downloading it.
+ ///
+ /// Value indicating whether to fetch the Ant optional tasks.
+ /// The token to cancel the operation.
+ /// The path to the installation directory.
+ public async Task Install(bool optionalTasks = false, CancellationToken cancellationToken = default) {
+ var antHome = await Download(optionalTasks, cancellationToken);
+
+ var binFolder = Path.Join(antHome, "bin");
+ Environment.SetEnvironmentVariable("PATH", $"{Environment.GetEnvironmentVariable("PATH")}{Path.PathSeparator}{binFolder}");
+ await File.AppendAllTextAsync(Environment.GetEnvironmentVariable("GITHUB_PATH")!, binFolder, cancellationToken);
+
+ Environment.SetEnvironmentVariable("ANT_HOME", antHome);
+ await File.AppendAllTextAsync(Environment.GetEnvironmentVariable("GITHUB_ENV")!, $"ANT_HOME={antHome}", cancellationToken);
+ return antHome;
+ }
+
+ ///
+ /// Fetches the external libraries required by Ant optional tasks.
+ ///
+ /// The path to the Ant directory.
+ /// Completes when the external libraries have been fetched.
+ /// An error occurred while fetching the external libraries.
+ private static async Task FetchOptionalTasks(string antHome) {
+ var startInfo = new ProcessStartInfo {
+ Arguments = "-jar lib/ant-launcher.jar -buildfile fetch.xml -noinput -silent -Ddest=system",
+ CreateNoWindow = true,
+ EnvironmentVariables = { ["ANT_HOME"] = antHome },
+ FileName = "java",
+ WorkingDirectory = antHome
+ };
+
+ using var process = Process.Start(startInfo) ?? throw new ApplicationFailedException(startInfo.FileName);
+ await process.WaitForExitAsync();
+ if (process.ExitCode != 0) throw new ApplicationFailedException(startInfo.FileName);
+ }
+}
diff --git a/src/Setup.psm1 b/src/Setup.psm1
deleted file mode 100644
index bedf164..0000000
--- a/src/Setup.psm1
+++ /dev/null
@@ -1,116 +0,0 @@
-using namespace System.Diagnostics.CodeAnalysis
-using namespace System.IO
-using module ./Release.psm1
-
-<#
-.SYNOPSIS
- Manages the download and installation of Apache Ant.
-#>
-class Setup {
-
- <#
- .SYNOPSIS
- The release to download and install.
- #>
- [ValidateNotNull()]
- hidden [Release] $Release
-
- <#
- .SYNOPSIS
- Creates a new setup.
- .PARAMETER Release
- The release to download and install.
- #>
- Setup([Release] $Release) {
- $this.Release = $Release
- }
-
- <#
- .SYNOPSIS
- Downloads and extracts the ZIP archive of Apache Ant.
- .OUTPUTS
- The path to the extracted directory.
- #>
- [string] Download() {
- return $this.Download($false)
- }
-
- <#
- .SYNOPSIS
- Downloads and extracts the ZIP archive of Apache Ant.
- .PARAMETER OptionalTasks
- Value indicating whether to fetch the Ant optional tasks.
- .OUTPUTS
- The path to the extracted directory.
- #>
- [string] Download([bool] $OptionalTasks) {
- $file = New-TemporaryFile
- Invoke-WebRequest $this.Release.Url() -OutFile $file
-
- $directory = Join-Path ([Path]::GetTempPath()) (New-Guid)
- Expand-Archive $file $directory -Force
-
- $antHome = Join-Path $directory $this.FindSubfolder($directory)
- if ($OptionalTasks) { $this.FetchOptionalTasks($antHome) }
- return $antHome
- }
-
- <#
- .SYNOPSIS
- Installs Apache Ant, after downloading it.
- .OUTPUTS
- The path to the installation directory.
- #>
- [string] Install() {
- return $this.Install($false)
- }
-
- <#
- .SYNOPSIS
- Installs Apache Ant, after downloading it.
- .PARAMETER OptionalTasks
- Value indicating whether to fetch the Ant optional tasks.
- .OUTPUTS
- The path to the installation directory.
- #>
- [string] Install([bool] $OptionalTasks) {
- $antHome = $this.Download($OptionalTasks)
-
- $binFolder = Join-Path $antHome "bin"
- $Env:PATH += "$([Path]::PathSeparator)$binFolder"
- Add-Content $Env:GITHUB_PATH $binFolder
-
- $Env:ANT_HOME = $antHome
- Add-Content $Env:GITHUB_ENV "ANT_HOME=$Env:ANT_HOME"
- return $antHome
- }
-
- <#
- .SYNOPSIS
- Fetches the external libraries required by Ant optional tasks.
- .PARAMETER AntHome
- The path to the Ant directory.
- #>
- hidden [void] FetchOptionalTasks([string] $AntHome) {
- $options = "-jar lib/ant-launcher.jar -buildfile fetch.xml -noinput -silent -Ddest=system"
- Start-Process java $options -Environment @{ ANT_HOME = $AntHome } -NoNewWindow -Wait -WorkingDirectory $AntHome
- }
-
- <#
- .SYNOPSIS
- Determines the name of the single subfolder in the specified directory.
- .PARAMETER Directory
- The directory path.
- .OUTPUTS
- The name of the single subfolder in the specified directory.
- #>
- [SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "")]
- hidden [string] FindSubfolder([string] $Directory) {
- $folders = Get-ChildItem $Directory -Directory
- return $discard = switch ($folders.Count) {
- 0 { throw [DirectoryNotFoundException] "No subfolder found in: $Directory." }
- 1 { $folders[0].BaseName; break }
- default { throw [DirectoryNotFoundException] "Multiple subfolders found in: $Directory." }
- }
- }
-}
diff --git a/src/SetupAnt.csproj b/src/SetupAnt.csproj
new file mode 100644
index 0000000..b2b5ec9
--- /dev/null
+++ b/src/SetupAnt.csproj
@@ -0,0 +1,27 @@
+
+
+ Cedric-Belin.fr
+ © Cédric Belin
+ Set up your GitHub Actions workflow with a specific version of Apache Ant.
+ Setup Ant
+ 5.1.0
+
+
+
+ false
+ Belin.SetupAnt
+ true
+ enable
+ enable
+ ../bin
+ net8.0
+
+
+
+
+
+
+
+
+
+
diff --git a/src/SetupAnt.esproj b/src/SetupAnt.esproj
deleted file mode 100644
index a2c426d..0000000
--- a/src/SetupAnt.esproj
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- ../
- false
- false
-
-
diff --git a/test/AssemblyInfo.cs b/test/AssemblyInfo.cs
new file mode 100644
index 0000000..300f5b1
--- /dev/null
+++ b/test/AssemblyInfo.cs
@@ -0,0 +1 @@
+[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)]
diff --git a/test/Cmdlets/BeforeAll.ps1 b/test/Cmdlets/BeforeAll.ps1
new file mode 100644
index 0000000..8820445
--- /dev/null
+++ b/test/Cmdlets/BeforeAll.ps1
@@ -0,0 +1,5 @@
+Import-Module "$PSScriptRoot/../../SetupAnt.psd1"
+
+$existingRelease = New-AntRelease "1.10.15"
+$latestRelease = Get-AntRelease "Latest"
+$nonExistingRelease = New-AntRelease "666.6.6"
diff --git a/test/Cmdlets/Find-Release.Tests.ps1 b/test/Cmdlets/Find-Release.Tests.ps1
new file mode 100644
index 0000000..f67f6bd
--- /dev/null
+++ b/test/Cmdlets/Find-Release.Tests.ps1
@@ -0,0 +1,28 @@
+<#
+.SYNOPSIS
+ Tests the features of the `Find-Release` cmdlet.
+#>
+Describe "Find-Release" {
+ BeforeAll {
+ . "$PSScriptRoot/BeforeAll.ps1"
+ }
+
+ It "should return `$null if no release matches the version constraint" {
+ Find-AntRelease $nonExistingRelease.Version | Should -Be $null
+ }
+
+ It "should return the release corresponding to the version constraint if it exists" {
+ Find-AntRelease "latest" | Should -Be $latestRelease
+ Find-AntRelease "*" | Should -Be $latestRelease
+ Find-AntRelease "1" | Should -Be $latestRelease
+ Find-AntRelease "2" | Should -Be $null
+ (Find-AntRelease ">1.10.15")?.Version | Should -Be $null
+ (Find-AntRelease "=1.8.2")?.Version | Should -Be "1.8.2"
+ (Find-AntRelease "<1.10")?.Version | Should -Be "1.9.16"
+ (Find-AntRelease "<=1.10")?.Version | Should -Be "1.10.0"
+ }
+
+ It "should throw if the version constraint is invalid" -TestCases @{ Version = "abc" }, @{ Version = "?1.10" } {
+ { Find-AntRelease $version } | Should -Throw
+ }
+}
diff --git a/test/Cmdlets/Get-Release.Tests.ps1 b/test/Cmdlets/Get-Release.Tests.ps1
new file mode 100644
index 0000000..badcd49
--- /dev/null
+++ b/test/Cmdlets/Get-Release.Tests.ps1
@@ -0,0 +1,17 @@
+<#
+.SYNOPSIS
+ Tests the features of the `Get-Release` cmdlet.
+#>
+Describe "Get-Release" {
+ BeforeAll {
+ . "$PSScriptRoot/BeforeAll.ps1"
+ }
+
+ It "should return `$null if no release matches to the version number" {
+ Get-AntRelease $nonExistingRelease.Version | Should -Be $null
+ }
+
+ It "should return the release corresponding to the version number if it exists" {
+ (Get-AntRelease "1.8.2")?.Version | Should -Be "1.8.2"
+ }
+}
diff --git a/test/Cmdlets/Test-Release.Tests.ps1 b/test/Cmdlets/Test-Release.Tests.ps1
new file mode 100644
index 0000000..030327c
--- /dev/null
+++ b/test/Cmdlets/Test-Release.Tests.ps1
@@ -0,0 +1,24 @@
+<#
+.SYNOPSIS
+ Tests the features of the `Test-Release` cmdlet.
+#>
+Describe "Test-Release" {
+ BeforeAll {
+ . "$PSScriptRoot/BeforeAll.ps1"
+ }
+
+ It "should return `$true for the latest release" {
+ Test-AntRelease $latestRelease.Version | Should -BeTrue
+ $latestRelease | Test-AntRelease | Should -BeTrue
+ }
+
+ It "should return `$true if the release exists" {
+ Test-AntRelease $existingRelease.Version | Should -BeTrue
+ $existingRelease | Test-AntRelease | Should -BeTrue
+ }
+
+ It "should return `$false if the release does not exist" {
+ Test-AntRelease $nonExistingRelease.Version | Should -BeFalse
+ $nonExistingRelease | Test-AntRelease | Should -BeFalse
+ }
+}
diff --git a/test/Main.Tests.ps1 b/test/Main.Tests.ps1
deleted file mode 100644
index e923c6a..0000000
--- a/test/Main.Tests.ps1
+++ /dev/null
@@ -1,68 +0,0 @@
-using namespace System.Diagnostics.CodeAnalysis
-
-<#
-.SYNOPSIS
- Tests the features of the `Main` module.
-#>
-Describe "Main" {
- BeforeAll {
- Import-Module ./SetupAnt.psd1
-
- [SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "")]
- $existingRelease = New-AntRelease "1.10.15"
-
- [SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "")]
- $latestRelease = Get-AntRelease "Latest"
-
- [SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "")]
- $nonExistingRelease = New-AntRelease "666.6.6"
- }
-
- Context "Find-Release" {
- It "should return `$null if no release matches the version constraint" {
- Find-AntRelease $nonExistingRelease.Version | Should -Be $null
- }
-
- It "should return the release corresponding to the version constraint if it exists" {
- Find-AntRelease "latest" | Should -Be $latestRelease
- Find-AntRelease "*" | Should -Be $latestRelease
- Find-AntRelease "1" | Should -Be $latestRelease
- Find-AntRelease "2" | Should -Be $null
- (Find-AntRelease ">1.10.15")?.Version | Should -Be $null
- (Find-AntRelease "=1.8.2")?.Version | Should -Be "1.8.2"
- (Find-AntRelease "<1.10")?.Version | Should -Be "1.9.16"
- (Find-AntRelease "<=1.10")?.Version | Should -Be "1.10.0"
- }
-
- It "should throw if the version constraint is invalid" -TestCases @{ Version = "abc" }, @{ Version = "?1.10" } {
- { Find-AntRelease $version } | Should -Throw
- }
- }
-
- Context "Get-Release" {
- It "should return `$null if no release matches to the version number" {
- Get-AntRelease $nonExistingRelease.Version | Should -Be $null
- }
-
- It "should return the release corresponding to the version number if it exists" {
- (Get-AntRelease "1.8.2")?.Version | Should -Be "1.8.2"
- }
- }
-
- Context "Test-Release" {
- It "should return `$true for the latest release" {
- Test-AntRelease $latestRelease.Version | Should -BeTrue
- $latestRelease | Test-AntRelease | Should -BeTrue
- }
-
- It "should return `$true if the release exists" {
- Test-AntRelease $existingRelease.Version | Should -BeTrue
- $existingRelease | Test-AntRelease | Should -BeTrue
- }
-
- It "should return `$false if the release does not exist" {
- Test-AntRelease $nonExistingRelease.Version | Should -BeFalse
- $nonExistingRelease | Test-AntRelease | Should -BeFalse
- }
- }
-}
diff --git a/test/Release.Tests.cs b/test/Release.Tests.cs
new file mode 100644
index 0000000..c4d9168
--- /dev/null
+++ b/test/Release.Tests.cs
@@ -0,0 +1,55 @@
+namespace Belin.SetupAnt;
+
+///
+/// Tests the features of the class.
+///
+/// The test context.
+[TestClass]
+public sealed class ReleaseTests {
+
+ ///
+ /// A release that exists.
+ ///
+ private readonly Release existingRelease = new("1.10.15");
+
+ ///
+ /// A release that does not exist.
+ ///
+ private readonly Release nonExistingRelease = new("666.6.6");
+
+ [TestMethod]
+ public void Exists() {
+ IsTrue(existingRelease.Exists);
+ IsFalse(nonExistingRelease.Exists);
+ }
+
+ [TestMethod]
+ public void Url() {
+ AreEqual(new Uri("https://downloads.apache.org/ant/binaries/apache-ant-1.10.15-bin.zip"), existingRelease.Url);
+ AreEqual(new Uri("https://archive.apache.org/dist/ant/binaries/apache-ant-666.6.6-bin.zip"), nonExistingRelease.Url);
+ }
+
+ [TestMethod]
+ public void Find() {
+ IsNull(Release.Find(nonExistingRelease.Version.ToString()));
+ IsNull(Release.Find("2"));
+ IsNull(Release.Find(">1.10.15"));
+
+ AreEqual(Release.Latest, Release.Find("latest"));
+ AreEqual(Release.Latest, Release.Find("*"));
+ AreEqual(Release.Latest, Release.Find("1"));
+
+ AreEqual(new Release("1.8.2"), Release.Find("=1.8.2"));
+ AreEqual(new Release("1.9.16"), Release.Find("<1.10"));
+ AreEqual(new Release("1.10.0"), Release.Find("<=1.10"));
+
+ Throws(() => Release.Find("abc"));
+ Throws(() => Release.Find("?1.10"));
+ }
+
+ [TestMethod]
+ public void Get() {
+ IsNull(Release.Get(nonExistingRelease.Version));
+ AreEqual(Release.Get("1.8.2")?.Version, Version.Parse("1.8.2"));
+ }
+}
diff --git a/test/Release.Tests.ps1 b/test/Release.Tests.ps1
deleted file mode 100644
index 880f1a7..0000000
--- a/test/Release.Tests.ps1
+++ /dev/null
@@ -1,73 +0,0 @@
-using namespace System.Diagnostics.CodeAnalysis
-using module ../src/Release.psm1
-
-<#
-.SYNOPSIS
- Tests the features of the `Release` module.
-#>
-Describe "Release" {
- BeforeAll {
- [SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "")]
- $existingRelease = [Release] "1.10.15"
-
- [SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "")]
- $latestRelease = [Release]::Latest()
-
- [SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "")]
- $nonExistingRelease = [Release] "666.6.6"
- }
-
- Context "Exists" {
- It "should return `$true if the release exists" {
- $existingRelease.Exists() | Should -BeTrue
- }
-
- It "should return `$false if the release does not exist" {
- $nonExistingRelease.Exists() | Should -BeFalse
- }
- }
-
- Context "Url" {
- It "should return the URL of the Ant archive" {
- $existingRelease.Url() | Should -BeExactly "https://archive.apache.org/dist/ant/binaries/apache-ant-1.10.15-bin.zip"
- $nonExistingRelease.Url() | Should -BeExactly "https://archive.apache.org/dist/ant/binaries/apache-ant-666.6.6-bin.zip"
- }
- }
-
- Context "Find" {
- It "should return `$null if no release matches the version constraint" {
- [Release]::Find($nonExistingRelease.Version) | Should -Be $null
- }
-
- It "should return the release corresponding to the version constraint if it exists" {
- [Release]::Find("latest") | Should -Be $latestRelease
- [Release]::Find("*") | Should -Be $latestRelease
- [Release]::Find("1") | Should -Be $latestRelease
- [Release]::Find("2") | Should -Be $null
- [Release]::Find(">1.10.15")?.Version | Should -Be $null
- [Release]::Find("=1.8.2")?.Version | Should -Be "1.8.2"
- [Release]::Find("<1.10")?.Version | Should -Be "1.9.16"
- [Release]::Find("<=1.10")?.Version | Should -Be "1.10.0"
- }
-
- It "should throw if the version constraint is invalid" -TestCases @{ Version = "abc" }, @{ Version = "?1.10" } {
- { [Release]::Find($version) } | Should -Throw
- }
- }
-
- Context "Get" {
- It "should return `$null if no release matches to the version number" {
- [Release]::Get($nonExistingRelease.Version) | Should -Be $null
- }
-
- It "should return the release corresponding to the version number if it exists" {
- [Release]::Get("1.8.2")?.Version | Should -Be "1.8.2"
- }
- }
-
- Context "Latest" {
- It "should exist" {
- $latestRelease | Should -Not -Be $null
- }
- }
-}
diff --git a/test/Setup.Tests.cs b/test/Setup.Tests.cs
new file mode 100644
index 0000000..181b570
--- /dev/null
+++ b/test/Setup.Tests.cs
@@ -0,0 +1,31 @@
+namespace Belin.SetupAnt;
+
+///
+/// Tests the features of the class.
+///
+/// The test context.
+[TestClass]
+public sealed class SetupTests(TestContext testContext) {
+
+ [ClassInitialize]
+ public static void ClassInitialize(TestContext testContext) {
+ if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_ENV"))) Environment.SetEnvironmentVariable("GITHUB_ENV", "var/GitHub-Env.txt");
+ if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITHUB_PATH"))) Environment.SetEnvironmentVariable("GITHUB_PATH", "var/GitHub-Path.txt");
+ }
+
+ [TestMethod]
+ public async Task Download() {
+ var path = await new Setup(Release.Latest).Download(optionalTasks: true, testContext.CancellationToken);
+ IsTrue(File.Exists(Path.Join(path, "bin", OperatingSystem.IsWindows() ? "ant.cmd" : "ant")));
+
+ var jars = Directory.EnumerateFiles(Path.Join(path, "lib"), "*.jar");
+ HasCount(1, jars.Where(jar => Path.GetFileName(jar).StartsWith("ivy-")));
+ }
+
+ [TestMethod]
+ public async Task Install() {
+ var path = await new Setup(Release.Latest).Install(optionalTasks: false, testContext.CancellationToken);
+ AreEqual(path, Environment.GetEnvironmentVariable("ANT_HOME"));
+ Contains(path, Environment.GetEnvironmentVariable("PATH")!);
+ }
+}
diff --git a/test/Setup.Tests.ps1 b/test/Setup.Tests.ps1
deleted file mode 100644
index 374337a..0000000
--- a/test/Setup.Tests.ps1
+++ /dev/null
@@ -1,34 +0,0 @@
-using namespace System.Diagnostics.CodeAnalysis
-using module ../src/Release.psm1
-using module ../src/Setup.psm1
-
-<#
-.SYNOPSIS
- Tests the features of the `Setup` module.
-#>
-Describe "Setup" {
- BeforeAll {
- [SuppressMessage("PSUseDeclaredVarsMoreThanAssignments", "")]
- $latestRelease = [Release]::Latest()
-
- if (-not (Test-Path Env:GITHUB_ENV)) { $Env:GITHUB_ENV = "var/GitHub-Env.txt" }
- if (-not (Test-Path Env:GITHUB_PATH)) { $Env:GITHUB_PATH = "var/GitHub-Path.txt" }
- }
-
- Context "Download" {
- It "should properly download and extract Apache Ant" {
- $path = [Setup]::new($latestRelease).Download($true)
- Join-Path $path "bin/$($IsWindows ? "ant.cmd" : "ant")" | Should -Exist
- $jars = Get-Item (Join-Path $path "lib/*.jar")
- $jars.Where{ $_.BaseName.StartsWith("ivy-") } | Should -HaveCount 1
- }
- }
-
- Context "Install" {
- It "should add the Ant directory to the PATH environment variable" {
- $path = [Setup]::new($latestRelease).Install($false)
- $Env:ANT_HOME | Should -BeExactly $path
- $Env:PATH | Should -BeLikeExactly "*$path*"
- }
- }
-}
diff --git a/test/SetupAnt.Tests.csproj b/test/SetupAnt.Tests.csproj
new file mode 100644
index 0000000..e283fc1
--- /dev/null
+++ b/test/SetupAnt.Tests.csproj
@@ -0,0 +1,30 @@
+
+
+ Cedric-Belin.fr
+ © Cédric Belin
+ Setup Ant
+ 5.1.0
+
+
+
+ false
+ Belin.SetupAnt.Tests
+ obj
+ enable
+ enable
+ ../bin
+ en
+ net8.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/SetupAnt.Tests.esproj b/test/SetupAnt.Tests.esproj
deleted file mode 100644
index a2c426d..0000000
--- a/test/SetupAnt.Tests.esproj
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
- ../
- false
- false
-
-
diff --git a/tool/Build.ps1 b/tool/Build.ps1
new file mode 100644
index 0000000..0b76275
--- /dev/null
+++ b/tool/Build.ps1
@@ -0,0 +1,2 @@
+"Building the solution..."
+dotnet build --configuration ($Release ? "Release" : "Debug")
diff --git a/tool/Clean.ps1 b/tool/Clean.ps1
index 7a9909c..ffc27f0 100644
--- a/tool/Clean.ps1
+++ b/tool/Clean.ps1
@@ -1,2 +1,4 @@
"Deleting all generated files..."
+Remove-Item "bin" -ErrorAction Ignore -Force -Recurse
+Remove-Item "*/obj" -Force -Recurse
Remove-Item "var/*" -Exclude ".gitkeep" -Force -Recurse
diff --git a/tool/Default.ps1 b/tool/Default.ps1
index 4e1a44f..b3a7a6a 100644
--- a/tool/Default.ps1
+++ b/tool/Default.ps1
@@ -1 +1,3 @@
& "$PSScriptRoot/Clean.ps1"
+& "$PSScriptRoot/Version.ps1"
+& "$PSScriptRoot/Build.ps1"
diff --git a/tool/Format.ps1 b/tool/Format.ps1
new file mode 100644
index 0000000..d968024
--- /dev/null
+++ b/tool/Format.ps1
@@ -0,0 +1,2 @@
+"Formatting the source code..."
+dotnet format
diff --git a/tool/Lint.ps1 b/tool/Lint.ps1
index db91afb..055a902 100644
--- a/tool/Lint.ps1
+++ b/tool/Lint.ps1
@@ -1,6 +1,5 @@
"Performing the static analysis of source code..."
Import-Module PSScriptAnalyzer
Invoke-ScriptAnalyzer $PSScriptRoot -Recurse
-Invoke-ScriptAnalyzer src -Recurse
Invoke-ScriptAnalyzer test -Recurse
Test-ModuleManifest SetupAnt.psd1 | Out-Null
diff --git a/tool/Outdated.ps1 b/tool/Outdated.ps1
new file mode 100644
index 0000000..be4b30f
--- /dev/null
+++ b/tool/Outdated.ps1
@@ -0,0 +1,2 @@
+"Checking for outdated dependencies..."
+dotnet package list --outdated
diff --git a/tool/Test.ps1 b/tool/Test.ps1
index 226e684..95b5db9 100644
--- a/tool/Test.ps1
+++ b/tool/Test.ps1
@@ -1,4 +1,5 @@
"Running the test suite..."
+dotnet test --settings .runsettings
pwsh -Command {
Import-Module Pester
Invoke-Pester test
diff --git a/tool/Version.ps1 b/tool/Version.ps1
new file mode 100644
index 0000000..b623de3
--- /dev/null
+++ b/tool/Version.ps1
@@ -0,0 +1,5 @@
+"Updating the version number in the sources..."
+$version = (Import-PowerShellDataFile "SetupAnt.psd1").ModuleVersion
+foreach ($item in Get-Item "*/*.csproj") {
+ (Get-Content $item) -replace "\d+(\.\d+){2}", "$version" | Out-File $item
+}
diff --git a/tool/Watch.ps1 b/tool/Watch.ps1
new file mode 100644
index 0000000..7582a8b
--- /dev/null
+++ b/tool/Watch.ps1
@@ -0,0 +1,3 @@
+"Watching for file changes..."
+$configuration = $Release ? "Release" : "Debug"
+Start-Process dotnet "watch build --configuration $configuration" -NoNewWindow -Wait -WorkingDirectory src