Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/docs/operator/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ This command:
- Generates the necessary CRDs
- Installs them into your current Kubernetes context

:::tip[Solution files]
Instead of a `.csproj` file, you can pass a `.sln` or `.slnx` solution file. The CLI will compile all projects in the solution and search them for custom resources.
:::

:::warning[Production Usage]
The `install` and `uninstall` commands are primarily intended for development purposes. In production, you should use the generated Kubernetes manifests and your preferred deployment method (e.g., Helm, Kustomize, or GitOps).
:::
Expand Down
19 changes: 13 additions & 6 deletions src/KubeOps.Cli/Arguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace KubeOps.Cli;

internal static class Arguments
{
public static readonly Argument<FileInfo> SolutionOrProjectFile = new("sln/csproj file")
public static readonly Argument<FileInfo> SolutionOrProjectFile = new("sln/slnx/csproj file")
{
DefaultValueFactory = result =>
{
Expand All @@ -24,10 +24,17 @@ var slnFile
"*.sln")
.Select(f => new FileInfo(f))
.FirstOrDefault();
var file = (projectFile, slnFile) switch
var slnxFile
= Directory.EnumerateFiles(
Directory.GetCurrentDirectory(),
"*.slnx")
.Select(f => new FileInfo(f))
.FirstOrDefault();
var file = (projectFile, slnFile, slnxFile) switch
{
({ } prj, _) => prj,
(_, { } sln) => sln,
({ } prj, _, _) => prj,
(_, { } sln, _) => sln,
(_, _, { } slnx) => slnx,
_ => null,
};

Expand All @@ -40,8 +47,8 @@ var slnFile
return new FileInfo("not-found");
},
Description = "A solution or project file where entities are located. " +
"If omitted, the current directory is searched for a *.csproj or *.sln file. " +
"If an *.sln file is used, all projects in the solution (with the newest framework) will be searched for entities. " +
"If omitted, the current directory is searched for a *.csproj, *.sln, or *.slnx file. " +
"If an *.sln or *.slnx file is used, all projects in the solution (with the newest framework) will be searched for entities. " +
"This behaviour can be filtered by using the --project and --target-framework option.",
};

Expand Down
8 changes: 4 additions & 4 deletions src/KubeOps.Cli/Commands/Generator/OperatorGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ internal static async Task<int> Handler(IAnsiConsole console, ParseResult parseR
var parser = file switch
{
{ Extension: ".csproj", Exists: true } => await AssemblyLoader.ForProject(console, file),
{ Extension: ".sln", Exists: true } => await AssemblyLoader.ForSolution(
{ Extension: ".sln" or ".slnx", Exists: true } => await AssemblyLoader.ForSolution(
console,
file,
parseResult.GetValue(Options.SolutionProjectRegex),
parseResult.GetValue(Options.TargetFramework)),
{ Exists: false } => throw new FileNotFoundException($"The file {file.Name} does not exist."),
_ => throw new NotSupportedException("Only *.csproj and *.sln files are supported."),
_ => throw new NotSupportedException("Only *.csproj, *.sln, and *.slnx files are supported."),
};

var mutators = parser.GetMutatedEntities().ToList();
Expand Down Expand Up @@ -175,11 +175,11 @@ internal static async Task<int> Handler(IAnsiConsole console, ParseResult parseR
}
catch (Exception e)
{
console.MarkupLine($"[red]Could not clear output path: {e.Message}[/]");
console.MarkupLineInterpolated($"[red]Could not clear output path: {e.Message}[/]");
}
}

console.MarkupLine($"[green]Write output to {outPath}.[/]");
console.MarkupLineInterpolated($"[green]Write output to {outPath}.[/]");
await result.Write(outPath);
}
else
Expand Down
8 changes: 4 additions & 4 deletions src/KubeOps.Cli/Commands/Management/Install.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ internal static async Task<int> Handler(IAnsiConsole console, IKubernetes client
var parser = file switch
{
{ Extension: ".csproj", Exists: true } => await AssemblyLoader.ForProject(console, file),
{ Extension: ".sln", Exists: true } => await AssemblyLoader.ForSolution(
{ Extension: ".sln" or ".slnx", Exists: true } => await AssemblyLoader.ForSolution(
console,
file,
parseResult.GetValue(Options.SolutionProjectRegex),
parseResult.GetValue(Options.TargetFramework)),
{ Exists: false } => throw new FileNotFoundException($"The file {file.Name} does not exist."),
_ => throw new NotSupportedException("Only *.csproj and *.sln files are supported."),
_ => throw new NotSupportedException("Only *.csproj, *.sln, and *.slnx files are supported."),
};

console.WriteLine($"Install CRDs from {file.Name}.");
Expand Down Expand Up @@ -103,13 +103,13 @@ internal static async Task<int> Handler(IAnsiConsole console, IKubernetes client
}
catch (HttpOperationException)
{
console.WriteLine(
console.MarkupLineInterpolated(
$"""[red]There was a http (api) error while installing "{crd.Spec.Group}/{crd.Spec.Names.Kind}".[/]""");
throw;
}
catch (Exception)
{
console.WriteLine(
console.MarkupLineInterpolated(
$"""[red]There was an error while installing "{crd.Spec.Group}/{crd.Spec.Names.Kind}".[/]""");
throw;
}
Expand Down
8 changes: 4 additions & 4 deletions src/KubeOps.Cli/Commands/Management/Uninstall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ internal static async Task<int> Handler(IAnsiConsole console, IKubernetes client
var parser = file switch
{
{ Extension: ".csproj", Exists: true } => await AssemblyLoader.ForProject(console, file),
{ Extension: ".sln", Exists: true } => await AssemblyLoader.ForSolution(
{ Extension: ".sln" or ".slnx", Exists: true } => await AssemblyLoader.ForSolution(
console,
file,
parseResult.GetValue(Options.SolutionProjectRegex),
parseResult.GetValue(Options.TargetFramework)),
{ Exists: false } => throw new FileNotFoundException($"The file {file.Name} does not exist."),
_ => throw new NotSupportedException("Only *.csproj and *.sln files are supported."),
_ => throw new NotSupportedException("Only *.csproj, *.sln, and *.slnx files are supported."),
};

console.WriteLine($"Uninstall CRDs from {file.Name}.");
Expand Down Expand Up @@ -100,13 +100,13 @@ internal static async Task<int> Handler(IAnsiConsole console, IKubernetes client
}
catch (HttpOperationException)
{
console.WriteLine(
console.MarkupLineInterpolated(
$"""[red]There was a http (api) error while uninstalling "{crd.Spec.Group}/{crd.Spec.Names.Kind}".[/]""");
throw;
}
catch (Exception)
{
console.WriteLine(
console.MarkupLineInterpolated(
$"""[red]There was an error while uninstalling "{crd.Spec.Group}/{crd.Spec.Names.Kind}".[/]""");
throw;
}
Expand Down
11 changes: 8 additions & 3 deletions src/KubeOps.Cli/Transpilation/AssemblyLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,17 +116,22 @@ public static Task<MetadataLoadContext> ForSolution(
.Select(async p =>
{
console.MarkupLineInterpolated(
$"Load compilation context for [aqua]{p.name}[/]{(p.tfm.Length > 0 ? $" [grey]{p.tfm}[/]" : string.Empty)}.");
p.tfm.Length > 0
? (FormattableString)$"Load compilation context for [aqua]{p.name}[/] [grey]{p.tfm}[/]."
: (FormattableString)$"Load compilation context for [aqua]{p.name}[/].");

var compilation = await p.project.GetCompilationAsync();
console.MarkupLineInterpolated($"[green]Compilation context loaded for {p.name}.[/]");
if (compilation is null)
{
throw new AggregateException("Compilation could not be found.");
}

using var assemblyStream = new MemoryStream();
await using var assemblyStream = new MemoryStream();
console.MarkupLineInterpolated(
$"Start compilation for [aqua]{p.name}[/]{(p.tfm.Length > 0 ? $" [grey]{p.tfm}[/]" : string.Empty)}.");
p.tfm.Length > 0
? (FormattableString)$"Start compilation for [aqua]{p.name}[/] [grey]{p.tfm}[/]."
: (FormattableString)$"Start compilation for [aqua]{p.name}[/].");
switch (compilation.Emit(assemblyStream))
{
case { Success: false, Diagnostics: var diag }:
Expand Down
Loading