Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

containers/dotnet: add initial container #7

Merged
merged 1 commit into from
Nov 25, 2024
Merged
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
37 changes: 37 additions & 0 deletions containers/dotnet/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM mcr.microsoft.com/dotnet/sdk:6.0.414-jammy AS build

# TODO: We're currently bundling MakeItSo into the Docker image
# itself. This avoids having to make assumptions based on the
# command-line arguments, but leaves scope for inconsistency. At the
# moment, nothing *else* is in the Docker image... we could
# potentially include "everything needed for an unconfigured API" in
# the image, so that we could generate (but probably not build) an
# arbitrary library.

WORKDIR /src
COPY . ./
RUN dotnet build MakeItSo/MakeItSo.csproj -c Release

FROM mcr.microsoft.com/dotnet/sdk:6.0.414-jammy

# Additional tooling required to regenerate libraries and project files.
RUN apt-get update
RUN apt-get install -y unzip

WORKDIR /app
COPY --from=build /src/MakeItSo/bin/Release/net6.0 .
ENTRYPOINT ["dotnet", "MakeItSo.dll"]
31 changes: 31 additions & 0 deletions containers/dotnet/MakeItSo/ApiCatalog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace MakeItSo;

/// <summary>
/// // A very cut-down version of the code in Google.Cloud.Tools.Common.
/// </summary>
internal class ApiCatalog
{
/// <summary>
/// The APIs within the catalog.
/// </summary>
public List<ApiMetadata> Apis { get; set; } = null!;

/// <summary>
/// Proto paths for APIs we knowingly don't generate. The values are the reasons for not generating.
/// </summary>
public Dictionary<string, string> IgnoredPaths { get; set; } = null!;
}
22 changes: 22 additions & 0 deletions containers/dotnet/MakeItSo/ApiMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"):
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace MakeItSo;

// A very cut-down version of the code in Google.Cloud.Tools.Common.
internal class ApiMetadata
{
public string Id { get; set; } = null!;
public string ProtoPath { get; set; } = null!;
}
31 changes: 31 additions & 0 deletions containers/dotnet/MakeItSo/CreateCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"):
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace MakeItSo;

internal class CreateCommand : ICommand
{
private readonly string _apiRoot;
private readonly string _api;
private readonly string _outputRoot;

public CreateCommand(string apiRoot, string api, string outputRoot)
{
_apiRoot = apiRoot;
_api = api;
_outputRoot = outputRoot;
}

public void Execute() => throw new NotImplementedException();
}
20 changes: 20 additions & 0 deletions containers/dotnet/MakeItSo/ICommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"):
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace MakeItSo;

internal interface ICommand
{
void Execute();
}
14 changes: 14 additions & 0 deletions containers/dotnet/MakeItSo/MakeItSo.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

</Project>
90 changes: 90 additions & 0 deletions containers/dotnet/MakeItSo/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License").
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


// Quick and dirty prototype for an entry point for containerized generation.

using MakeItSo;

var namedArgs = new Dictionary<string, string>();

foreach (var arg in args)
{
if (!arg.StartsWith("--"))
{
Console.WriteLine($"Invalid argument: {arg}");
return 1;
}
else
{
var split = arg.Split('=', 2);
if (split.Length != 2)
{
Console.WriteLine($"Invalid argument: {arg}");
return 1;
}
namedArgs[split[0][2..]] = split[1];
}
}

var commandName = namedArgs.GetValueOrDefault("command");
if (commandName is null)
{
Console.WriteLine("No command specified.");
ShowHelp();
return 1;
}

ICommand? command;
try
{
command = namedArgs["command"] switch
{
"create" => new CreateCommand(namedArgs["api-root"], namedArgs["api"], namedArgs["output-root"]),
"update" => new UpdateCommand(namedArgs["api-root"], namedArgs["api"], namedArgs["output-root"]),
_ => null
};
}
catch (KeyNotFoundException ex)
{
Console.WriteLine(ex.Message);
ShowHelp();
return 1;
}

if (command is null)
{
Console.WriteLine($"Unknown command: {namedArgs["command"]}");
ShowHelp();
return 1;
}

try
{
command.Execute();
}
catch (Exception e)
{
Console.WriteLine($"Error executing command: {e}");
return 1;
}

return 0;

void ShowHelp()
{
Console.WriteLine("Valid commands:");
Console.WriteLine("--command=update --api-root=path-to-apis --api=relative-path-to-api --output-root=path-to-dotnet-repo");
Console.WriteLine("--command=create --api-root=path-to-apis --api=relative-path-to-api --output-root=path-to-dotnet-repo");
}
58 changes: 58 additions & 0 deletions containers/dotnet/MakeItSo/UpdateCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"):
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Diagnostics;

namespace MakeItSo;

internal class UpdateCommand : ICommand
{
private readonly string _apiRoot;
private readonly string _api;
private readonly string _outputRoot;

public UpdateCommand(string apiRoot, string api, string outputRoot)
{
_apiRoot = apiRoot;
_api = api;
_outputRoot = outputRoot;
}

public void Execute()
{
var apiCatalogJson = File.ReadAllText(Path.Combine(_outputRoot, "apis", "apis.json"));
var apiCatalog = JsonConvert.DeserializeObject<ApiCatalog>(apiCatalogJson)!;
var api = apiCatalog.Apis.FirstOrDefault(api => api.ProtoPath == _api);
if (api is null)
{
throw new Exception($"No API configured with proto path {_api}");
}

var psi = new ProcessStartInfo
{
FileName = "/bin/bash",
ArgumentList = { "./generateapis.sh", api.Id },
WorkingDirectory = _outputRoot,
EnvironmentVariables = { { "GOOGLEAPIS_DIR", _apiRoot } }
};
var process = Process.Start(psi)!;
process.WaitForExit();
if (process.ExitCode != 0)
{
throw new Exception($"Generation ended with exit code {process.ExitCode}");
}
}
}
Loading