diff --git a/sdk/dotnet/.editorconfig b/sdk/dotnet/.editorconfig new file mode 100644 index 00000000000..14c1d8c1953 --- /dev/null +++ b/sdk/dotnet/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true diff --git a/sdk/dotnet/.gitignore b/sdk/dotnet/.gitignore index 8a30d258ed9..a437a653013 100644 --- a/sdk/dotnet/.gitignore +++ b/sdk/dotnet/.gitignore @@ -1,21 +1,22 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +*.swp +*.*~ +project.lock.json +.DS_Store +*.pyc +nupkg/ + +# Visual Studio Code +.vscode + +# Rider +.idea # User-specific files -*.rsuser *.suo *.user *.userosscache *.sln.docstates -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - # Build results [Dd]ebug/ [Dd]ebugPublic/ @@ -23,376 +24,14 @@ mono_crash.* [Rr]eleases/ x64/ x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ +build/ bld/ [Bb]in/ [Oo]bj/ -[Ll]og/ -[Ll]ogs/ +[Oo]ut/ +msbuild.log +msbuild.err +msbuild.wrn -# Visual Studio 2015/2017 cache/options directory +# Visual Studio 2015 .vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.tlog -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio 6 auto-generated project file (contains which files were open etc.) -*.vbp - -# Visual Studio 6 workspace and project file (working project files containing files to include in project) -*.dsw -*.dsp - -# Visual Studio 6 technical files -*.ncb -*.aps - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# Visual Studio History (VSHistory) files -.vshistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd - -# VS Code files for those working on multiple tools -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json -*.code-workspace - -# Local History for Visual Studio Code -.history/ - -# Windows Installer files from build outputs -*.cab -*.msi -*.msix -*.msm -*.msp - -# JetBrains Rider -*.sln.iml diff --git a/sdk/dotnet/Dagger.SDK.Tests/Dagger.SDK.Tests.csproj b/sdk/dotnet/Dagger.SDK.Tests/Dagger.SDK.Tests.csproj new file mode 100644 index 00000000000..2180b388b94 --- /dev/null +++ b/sdk/dotnet/Dagger.SDK.Tests/Dagger.SDK.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + diff --git a/sdk/dotnet/Dagger.SDK.Tests/GraphQL/GraphQLClientTest.cs b/sdk/dotnet/Dagger.SDK.Tests/GraphQL/GraphQLClientTest.cs new file mode 100644 index 00000000000..2489777b42d --- /dev/null +++ b/sdk/dotnet/Dagger.SDK.Tests/GraphQL/GraphQLClientTest.cs @@ -0,0 +1,33 @@ +using System.Net; +using System.Net.Http.Json; +using Dagger.SDK.GraphQL; + +namespace Dagger.SDK.Tests.GraphQL; + +public class GraphQLClientTest +{ + [Fact] + public async void TestRequest() + { + var query = """ + query { + container { + from(address: "alpine:3.16") { + withExec(args: ["echo", "hello"]) { + stdout + } + } + } + } + """; + + var gqlCLient = new GraphQLClient(); + var response = await gqlCLient.RequestAsync(query); + + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + var gqlResponse = await response.Content.ReadFromJsonAsync(); + Assert.Null(gqlResponse!.Errors); + Assert.Equal("hello\n", gqlResponse!.Data.GetProperty("container").GetProperty("from").GetProperty("withExec").GetProperty("stdout").GetString()); + } +} diff --git a/sdk/dotnet/Dagger.SDK.Tests/GraphQL/QueryBuilderTest.cs b/sdk/dotnet/Dagger.SDK.Tests/GraphQL/QueryBuilderTest.cs new file mode 100644 index 00000000000..b7b005389cc --- /dev/null +++ b/sdk/dotnet/Dagger.SDK.Tests/GraphQL/QueryBuilderTest.cs @@ -0,0 +1,83 @@ +using Dagger.SDK.GraphQL; + +namespace Dagger.SDK.Tests.GraphQL; + +public class QueryBuilderTest +{ + [Fact] + public void TestSelect() + { + var query = QueryBuilder + .Builder() + .Select("container") + .Build(); + + Assert.Equal("query{container}", query); + } + + [Fact] + public void TestSelect_WithArgument() + { + var query = QueryBuilder + .Builder() + .Select("container") + .Select("from", [new Argument("address", new StringValue("nginx"))]) + .Build(); + + Assert.Equal("query{container{from(address:\"nginx\")}}", query); + + query = QueryBuilder + .Builder() + .Select("container") + .Select("withExec", [new Argument("args", new ListValue([new StringValue("echo"), new StringValue("hello")]))]) + .Build(); + + Assert.Equal("query{container{withExec(args:[\"echo\",\"hello\"])}}", query); + + query = QueryBuilder + .Builder() + .Select( + "buildDocker", + [ + new Argument( + "buildArgs", + new ObjectValue( + [ + KeyValuePair.Create("key", new StringValue("value") as Value) + ] + ) + ) + ] + ) + .Build(); + + Assert.Equal("query{buildDocker(buildArgs:{key:\"value\"})}", query); + + query = QueryBuilder + .Builder() + .Select("withEnvVariable", [new Argument("expand", new BooleanValue(true))]) + .Build(); + + Assert.Equal("query{withEnvVariable(expand:true)}", query); + } + + [Fact] + public void TestSelect_ImmutableQuery() + { + var query1 = QueryBuilder + .Builder() + .Select("envVariables"); + + var query2 = query1 + .Select("name") + .Build(); + + Assert.Equal("query{envVariables{name}}", query2); + + var query3 = query1 + .Select("value") + .Build(); + + Assert.Equal("query{envVariables{value}}", query3); + } +} diff --git a/sdk/dotnet/DaggerSDK/DaggerSDK.csproj b/sdk/dotnet/Dagger.SDK/Dagger.SDK.csproj similarity index 74% rename from sdk/dotnet/DaggerSDK/DaggerSDK.csproj rename to sdk/dotnet/Dagger.SDK/Dagger.SDK.csproj index a1ed5b3f0a7..bb23fb7d66b 100644 --- a/sdk/dotnet/DaggerSDK/DaggerSDK.csproj +++ b/sdk/dotnet/Dagger.SDK/Dagger.SDK.csproj @@ -1,9 +1,9 @@ - - - - net7.0 - enable - enable - - - + + + + net8.0 + enable + enable + + + diff --git a/sdk/dotnet/Dagger.SDK/Dagger.cs b/sdk/dotnet/Dagger.SDK/Dagger.cs new file mode 100644 index 00000000000..dea72f7839d --- /dev/null +++ b/sdk/dotnet/Dagger.SDK/Dagger.cs @@ -0,0 +1,5 @@ +namespace Dagger.SDK; + +public class Dagger +{ +} diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/Field.cs b/sdk/dotnet/Dagger.SDK/GraphQL/Field.cs new file mode 100644 index 00000000000..9f20625aef9 --- /dev/null +++ b/sdk/dotnet/Dagger.SDK/GraphQL/Field.cs @@ -0,0 +1,21 @@ +using System.Collections.Immutable; + +namespace Dagger.SDK.GraphQL; + +public class Argument(string key, Value value) +{ + public string Key { get; } = key; + public Value Value { get; } = value; + + public string FormatValue() + { + return Value.Format(); + } +} + +public class Field(string name, ImmutableList args) +{ + public string Name { get; } = name; + + public ImmutableList Args { get; } = args; +} diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLClient.cs b/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLClient.cs new file mode 100644 index 00000000000..37e0024bc40 --- /dev/null +++ b/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLClient.cs @@ -0,0 +1,42 @@ + +using System.Net.Http.Headers; +using System.Net.Http.Json; +using System.Text; + +namespace Dagger.SDK.GraphQL; + +/// +/// GraphQL client for Dagger. +/// +public class GraphQLClient +{ + private readonly HttpClient _httpClient; + + public GraphQLClient() : this(Environment.GetEnvironmentVariable("DAGGER_SESSION_PORT")!, Environment.GetEnvironmentVariable("DAGGER_SESSION_TOKEN")!) + { + } + + public GraphQLClient(string port, string token, string scheme = "http", string host = "localhost") + { + _httpClient = new HttpClient(); + _httpClient.DefaultRequestHeaders.Add("Authorization", BasicAuth(token)); + _httpClient.DefaultRequestHeaders.Add("Accept", "application/json"); + _httpClient.BaseAddress = new Uri($"{scheme}://{host}:{port}"); + } + + private static string BasicAuth(string token) + { + var usernamePassword = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{token}:")); + return $"Basic {usernamePassword}"; + } + + /// + /// Perform GraphQL request. + /// + /// GraphQL query. + /// Raw HTTP response. + public async Task RequestAsync(string query) + { + return await _httpClient.PostAsJsonAsync("/query", new { query }); + } +} diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLResponse.cs b/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLResponse.cs new file mode 100644 index 00000000000..5bc33967ba7 --- /dev/null +++ b/sdk/dotnet/Dagger.SDK/GraphQL/GraphQLResponse.cs @@ -0,0 +1,22 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Dagger.SDK.GraphQL; + +public class GraphQLError +{ + [JsonPropertyName("message")] + public required string Message { get; set; } + + [JsonPropertyName("path")] + public required List Path { get; set; } +} + +public class GraphQLResponse +{ + [JsonPropertyName("errors")] + public List? Errors { get; set; } + + [JsonPropertyName("data")] + public required JsonElement Data { get; set; } +} diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/QueryBuilder.cs b/sdk/dotnet/Dagger.SDK/GraphQL/QueryBuilder.cs new file mode 100644 index 00000000000..8e28eeac27f --- /dev/null +++ b/sdk/dotnet/Dagger.SDK/GraphQL/QueryBuilder.cs @@ -0,0 +1,60 @@ +using System.Collections.Immutable; +using System.Net; +using System.Text; + +namespace Dagger.SDK.GraphQL; + +public class QueryBuilder +{ + public readonly ImmutableList Path = []; + + public QueryBuilder() { } + + public QueryBuilder(ImmutableList children) + { + this.Path = children; + } + + public QueryBuilder Select(string name) + { + return Select(name, []); + } + + public QueryBuilder Select(string name, ImmutableList args) + { + return Select(new Field(name, args)); + } + + public QueryBuilder Select(Field field) + { + return new QueryBuilder(Path.Add(field)); + } + + /// + /// Build GraphQL query. + /// + /// GraphQL query string + public string Build() + { + var builder = new StringBuilder(); + builder.Append("query"); + foreach (var selection in Path) + { + builder.Append('{'); + builder.Append(selection.Name); + if (selection.Args.Count > 0) + { + builder.Append('('); + builder.Append(string.Join(",", selection.Args.Select(arg => $"{arg.Key}:{arg.FormatValue()}"))); + builder.Append(')'); + } + } + builder.Append(new string('}', Path.Count)); + return builder.ToString(); + } + + public static QueryBuilder Builder() + { + return new QueryBuilder(); + } +} diff --git a/sdk/dotnet/Dagger.SDK/GraphQL/Types.cs b/sdk/dotnet/Dagger.SDK/GraphQL/Types.cs new file mode 100644 index 00000000000..d0ee4a19850 --- /dev/null +++ b/sdk/dotnet/Dagger.SDK/GraphQL/Types.cs @@ -0,0 +1,83 @@ +using System.Text; + +namespace Dagger.SDK.GraphQL; + +public abstract class Value +{ + public abstract string Format(); +} + +public class StringValue(string s) : Value +{ + private readonly string value = s; + + public override string Format() + { + return $"\"{value}\""; + } +} + +public class IntValue(int n) : Value +{ + private readonly int value = n; + + public override string Format() + { + return value.ToString(); + } +} + +public class FloatValue(float f) : Value +{ + private readonly float value = f; + + public override string Format() + { + return value.ToString(); + } +} + +public class BooleanValue(bool f) : Value +{ + private readonly bool value = f; + + public override string Format() + { + if (value == true) + { + return "true"; + } + else + { + return "false"; + } + } +} + +public class ListValue(List list) : Value +{ + private readonly List value = list; + + public override string Format() + { + var builder = new StringBuilder(); + builder.Append('['); + builder.Append(string.Join(",", value.Select(element => element.Format()))); + builder.Append(']'); + return builder.ToString(); + } +} + +public class ObjectValue(List> obj) : Value +{ + private readonly List> value = obj; + + public override string Format() + { + var builder = new StringBuilder(); + builder.Append('{'); + builder.Append(string.Join(",", value.Select(kv => $"{kv.Key}:{kv.Value.Format()}"))); + builder.Append('}'); + return builder.ToString(); + } +} diff --git a/sdk/dotnet/Dagger.sln b/sdk/dotnet/Dagger.sln new file mode 100644 index 00000000000..21ff50592cd --- /dev/null +++ b/sdk/dotnet/Dagger.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dagger.SDK", "Dagger.SDK\Dagger.SDK.csproj", "{2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dagger.SDK.Tests", "Dagger.SDK.Tests\Dagger.SDK.Tests.csproj", "{9B811549-D265-4E16-AC82-48C364A827E3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E89D0C5-43BE-443B-BAD5-DEE6B1168E22}.Release|Any CPU.Build.0 = Release|Any CPU + {9B811549-D265-4E16-AC82-48C364A827E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B811549-D265-4E16-AC82-48C364A827E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B811549-D265-4E16-AC82-48C364A827E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B811549-D265-4E16-AC82-48C364A827E3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/sdk/dotnet/DaggerSDK.sln b/sdk/dotnet/DaggerSDK.sln deleted file mode 100644 index a97f5ea1d2b..00000000000 --- a/sdk/dotnet/DaggerSDK.sln +++ /dev/null @@ -1,42 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.4.33213.308 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DaggerSDK", "DaggerSDK\DaggerSDK.csproj", "{68892045-452C-4AA8-BA1A-978846A7803C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{134BD5AA-8DD2-4EEF-BBB4-393C4B631E8A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IntegrationTests", "Tests\IntegrationTests\IntegrationTests.csproj", "{A0C7B3A6-61C0-441C-8BD1-66517F08C14D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DaggerSDKCodeGen", "DaggerSDKCodeGen\DaggerSDKCodeGen.csproj", "{E05F4484-2F33-472E-B9D3-1D8AC5C4E414}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {68892045-452C-4AA8-BA1A-978846A7803C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {68892045-452C-4AA8-BA1A-978846A7803C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {68892045-452C-4AA8-BA1A-978846A7803C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {68892045-452C-4AA8-BA1A-978846A7803C}.Release|Any CPU.Build.0 = Release|Any CPU - {A0C7B3A6-61C0-441C-8BD1-66517F08C14D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A0C7B3A6-61C0-441C-8BD1-66517F08C14D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A0C7B3A6-61C0-441C-8BD1-66517F08C14D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A0C7B3A6-61C0-441C-8BD1-66517F08C14D}.Release|Any CPU.Build.0 = Release|Any CPU - {E05F4484-2F33-472E-B9D3-1D8AC5C4E414}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E05F4484-2F33-472E-B9D3-1D8AC5C4E414}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E05F4484-2F33-472E-B9D3-1D8AC5C4E414}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E05F4484-2F33-472E-B9D3-1D8AC5C4E414}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {A0C7B3A6-61C0-441C-8BD1-66517F08C14D} = {134BD5AA-8DD2-4EEF-BBB4-393C4B631E8A} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {578F7FE8-F7C2-4C2A-9AC1-7EAC171BA6A2} - EndGlobalSection -EndGlobal diff --git a/sdk/dotnet/DaggerSDK/ContainerBuilder.cs b/sdk/dotnet/DaggerSDK/ContainerBuilder.cs deleted file mode 100644 index b9605bb6072..00000000000 --- a/sdk/dotnet/DaggerSDK/ContainerBuilder.cs +++ /dev/null @@ -1,31 +0,0 @@ -using DaggerSDK.GraphQL; -using DaggerSDK.GraphQL.QueryElements; - -namespace DaggerSDK; - -public class ContainerBuilder -{ - public string Platform { get; set; } = ""; - public string BaseImage { get; set; } = ""; - public List Commands { get; set; } = new(); - - public GraphQLElement GetQuery() - { - var result = new Container(platform: Platform, new[] - { - new From(BaseImage) - }); - - var curr = result.Body[0]; - foreach (var c in Commands) - { - var sub = new WithExec(c); - curr.Body.Add(sub); - curr = sub; - } - - curr.Body.Add(new("stdout")); - curr.Body.Add(new("stderr")); - return result; - } -} diff --git a/sdk/dotnet/DaggerSDK/GraphQL/GraphQLClient.cs b/sdk/dotnet/DaggerSDK/GraphQL/GraphQLClient.cs deleted file mode 100644 index 8d5e27f6728..00000000000 --- a/sdk/dotnet/DaggerSDK/GraphQL/GraphQLClient.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Net.Http.Json; -using System.Text; - -namespace DaggerSDK.GraphQL; - -public class GraphQLClient -{ - private readonly HttpClient _http; - - public GraphQLClient() - { - var port = Environment.GetEnvironmentVariable("DAGGER_SESSION_PORT"); - var token = Environment.GetEnvironmentVariable("DAGGER_SESSION_TOKEN"); - token = Convert.ToBase64String(Encoding.UTF8.GetBytes(token + ":")); - var url = $"http://localhost:{port}/query"; - - _http = new HttpClient(); - _http.DefaultRequestHeaders.Add("Authorization", $"Basic {token}"); - _http.DefaultRequestHeaders.Add("Accept", "application/json"); - _http.BaseAddress= new Uri(url); - } - - public async Task RequestAsync(string body) - { - var content = JsonContent.Create(new { query = body }); - return await _http.PostAsync("", content); - } -} diff --git a/sdk/dotnet/DaggerSDK/GraphQL/GraphQLQuery.cs b/sdk/dotnet/DaggerSDK/GraphQL/GraphQLQuery.cs deleted file mode 100644 index 108a2ea0cc3..00000000000 --- a/sdk/dotnet/DaggerSDK/GraphQL/GraphQLQuery.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace DaggerSDK.GraphQL; - -public class GraphQLQuery -{ - public string Generate() - { - return ""; - } -} diff --git a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/Container.cs b/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/Container.cs deleted file mode 100644 index 47b48610b92..00000000000 --- a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/Container.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace DaggerSDK.GraphQL.QueryElements; - -public class Container : GraphQLElement -{ - public Container(string? platform = null, IEnumerable? sub = null) - { - Name = "container"; - if (!string.IsNullOrEmpty(platform)) - { - Params.Add("platform", platform); - } - - foreach (var element in sub ?? Enumerable.Empty()) - { - Body.Add(element); - } - } -} diff --git a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/From.cs b/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/From.cs deleted file mode 100644 index 4b47bf2121c..00000000000 --- a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/From.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace DaggerSDK.GraphQL.QueryElements; - -public class From : GraphQLElement -{ - public From(string? address, IEnumerable? sub = null) - { - Name = "from"; - if (!string.IsNullOrEmpty(address)) - { - Params.Add("address", address); - } - - foreach (var element in sub ?? Enumerable.Empty()) - { - Body.Add(element); - } - } -} diff --git a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/GraphQLElement.cs b/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/GraphQLElement.cs deleted file mode 100644 index 3d4558b35d0..00000000000 --- a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/GraphQLElement.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace DaggerSDK.GraphQL.QueryElements; - -public class GraphQLElement -{ - public GraphQLElement() - { - - } - - public GraphQLElement(string name) - { - Name = name; - } - - public string Label { get; set; } = ""; - public string Name { get; set; } = ""; - public Dictionary Params { get; set; } = new(); - public List Body { get; set; } = new(); -} diff --git a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/WithExec.cs b/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/WithExec.cs deleted file mode 100644 index 9db4fe8ee2f..00000000000 --- a/sdk/dotnet/DaggerSDK/GraphQL/QueryElements/WithExec.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace DaggerSDK.GraphQL.QueryElements; - -public class WithExec : GraphQLElement -{ - public WithExec(string[] args, IEnumerable? sub = null) - { - Name = "withExec"; - if (args != null) - { - Params.Add("args", args); - } - - foreach (var element in sub ?? Enumerable.Empty()) - { - Body.Add(element); - } - } -} diff --git a/sdk/dotnet/DaggerSDK/GraphQL/Serializer.cs b/sdk/dotnet/DaggerSDK/GraphQL/Serializer.cs deleted file mode 100644 index 4d37dab353d..00000000000 --- a/sdk/dotnet/DaggerSDK/GraphQL/Serializer.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System.Text; -using System.Text.Encodings.Web; -using System.Text.Json; -using System.Text.Unicode; -using DaggerSDK.GraphQL.QueryElements; - -namespace DaggerSDK.GraphQL; - -public class Serializer -{ - public static string Serialize(params GraphQLElement[] elements) - { - var result = new StringBuilder(); - result.Append("query {"); - PrintIndented(result, elements); - result.Append("\n}"); - return result.ToString(); - } - - private static void PrintIndented(StringBuilder result, GraphQLElement[] elements, int indent = 1) - { - if (elements.Length == 0) - { - return; - } - - var prefix = "\n"; - foreach (var e in elements) - { - result.Append(prefix); - prefix = ",\n"; - PrintIndented(result, e, indent); - } - } - private static void PrintIndented(StringBuilder result, GraphQLElement element, int indent) - { - AddIndent(result, indent); - if (!string.IsNullOrEmpty(element.Label)) - { - result.Append(element.Label).Append(": "); - } - - result.Append(element.Name); - AddArgs(result, element.Params); - - if (!element.Body.Any()) - { - return; - } - - result.Append(" {"); - - PrintIndented(result, element.Body.ToArray(), indent + 1); - - result.Append("\n"); - AddIndent(result, indent); - result.Append("}"); - } - - private static void AddArgs(StringBuilder result, Dictionary args) - { - if (args.Count < 1) - { - return; - } - - result.Append("("); - var prefix = ""; - foreach (var (k, v) in args) - { - result.Append(prefix); - prefix = ", "; - result.Append($"{k}: {JsonSerializer.Serialize(v)}"); - } - result.Append(")"); - - } - - private static void AddIndent(StringBuilder result, int indent) - { - for (int i = 0; i < indent; i++) - { - result.Append(" "); - } - } -} diff --git a/sdk/dotnet/DaggerSDKCodeGen/DaggerSDKCodeGen.csproj b/sdk/dotnet/DaggerSDKCodeGen/DaggerSDKCodeGen.csproj index 4de2f4593d0..e27611057c9 100644 --- a/sdk/dotnet/DaggerSDKCodeGen/DaggerSDKCodeGen.csproj +++ b/sdk/dotnet/DaggerSDKCodeGen/DaggerSDKCodeGen.csproj @@ -2,7 +2,7 @@ Exe - net7.0 + net8.0 enable enable diff --git a/sdk/dotnet/DaggerSDKCodeGen/Models/QueryField.cs b/sdk/dotnet/DaggerSDKCodeGen/Models/QueryField.cs index c954a711f8a..7a3defb7048 100644 --- a/sdk/dotnet/DaggerSDKCodeGen/Models/QueryField.cs +++ b/sdk/dotnet/DaggerSDKCodeGen/Models/QueryField.cs @@ -4,7 +4,7 @@ public class QueryField { public QueryArg[]? Args { get; set; } public string? DeprecationReason { get; set; } - public string? Description { get; set; } + public string? Description { get; set; } public bool IsDeprecated { get; set; } public string? Name { get; set; } public ArgType? Type { get; set; } diff --git a/sdk/dotnet/DaggerSDKCodeGen/Program.cs b/sdk/dotnet/DaggerSDKCodeGen/Program.cs index d074f4537fa..5ca71cf0a58 100644 --- a/sdk/dotnet/DaggerSDKCodeGen/Program.cs +++ b/sdk/dotnet/DaggerSDKCodeGen/Program.cs @@ -19,10 +19,11 @@ var directives = JsonSerializer.Deserialize>(schema.GetProperty("directives"), opt) ?? throw new Exception("Failed to deserialize directives"); var types = JsonSerializer.Deserialize>(schema.GetProperty("types"), opt) - ?? throw new Exception("Failed to deserialize types");; + ?? throw new Exception("Failed to deserialize types"); ; Console.WriteLine("Writing introspect-api.json"); -File.WriteAllText("introspect-api.json", JsonSerializer.Serialize(new { +File.WriteAllText("introspect-api.json", JsonSerializer.Serialize(new +{ directives = schema.GetProperty("directives"), types = schema.GetProperty("types"), }, opt)); diff --git a/sdk/dotnet/Tests/IntegrationTests/BasicConnect.cs b/sdk/dotnet/Tests/IntegrationTests/BasicConnect.cs deleted file mode 100644 index 31a43a022e8..00000000000 --- a/sdk/dotnet/Tests/IntegrationTests/BasicConnect.cs +++ /dev/null @@ -1,41 +0,0 @@ -using DaggerSDK.GraphQL; -using IntegrationTests.TestData; -using Newtonsoft.Json; - -namespace IntegrationTests; - -public class BasicTests -{ - [Test] - public async Task BasicConnectAsync() - { - var query = LaravelExample.RuntimeQuery; - var client = new GraphQLClient(); - var response = await client.RequestAsync(query); - var body = await response.Content.ReadAsStringAsync(); - var json = JsonConvert.DeserializeObject(body); - Console.WriteLine(JsonConvert.SerializeObject(json, Formatting.Indented)); - Assert.That((int)response.StatusCode, Is.EqualTo(200)); - } - - [Test] - public void CreateQuery() - { - var e = LaravelExample.RuntimeQueryElement; - var q = Serializer.Serialize(e).Replace("\\u0027", "'"); - Console.WriteLine(q); - Assert.That(q, Is.EqualTo(LaravelExample.RuntimeQuery.Replace("\r\n", "\n").Replace(" ", " "))); - } - - [Test] - public void ContainerBuilder() - { - var builder = LaravelExample.ContainerBuilder; - var builderQuery = Serializer.Serialize(builder.GetQuery()); - - var compare = LaravelExample.RuntimeQueryElement; - var expectedResult = Serializer.Serialize(compare); - - Assert.That(builderQuery, Is.EqualTo(expectedResult)); - } -} diff --git a/sdk/dotnet/Tests/IntegrationTests/IntegrationTests.csproj b/sdk/dotnet/Tests/IntegrationTests/IntegrationTests.csproj deleted file mode 100644 index de30691665a..00000000000 --- a/sdk/dotnet/Tests/IntegrationTests/IntegrationTests.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - net7.0 - enable - enable - - false - - - - - - - - - - - - - - - diff --git a/sdk/dotnet/Tests/IntegrationTests/TestData/LaravelExample.cs b/sdk/dotnet/Tests/IntegrationTests/TestData/LaravelExample.cs deleted file mode 100644 index 782a5ce1996..00000000000 --- a/sdk/dotnet/Tests/IntegrationTests/TestData/LaravelExample.cs +++ /dev/null @@ -1,80 +0,0 @@ -using DaggerSDK; -using DaggerSDK.GraphQL.QueryElements; - -namespace IntegrationTests.TestData; - -// taken from: -public class LaravelExample -{ - public static string RuntimeQuery = """ - query { - container(platform: "linux/amd64") { - from(address: "php:8.2-apache-buster") { - withExec(args: ["apt-get","update"]) { - withExec(args: ["apt-get","install","--yes","git-core"]) { - withExec(args: ["apt-get","install","--yes","zip"]) { - withExec(args: ["apt-get","install","--yes","curl"]) { - withExec(args: ["docker-php-ext-install","pdo","pdo_mysql","mysqli"]) { - withExec(args: ["sh","-c","sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf"]) { - withExec(args: ["sh","-c","sed -ri -e 's!/var/www/!/var/www/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf"]) { - withExec(args: ["a2enmod","rewrite"]) { - stdout, - stderr - } - } - } - } - } - } - } - } - } - } - } - """; - - public static GraphQLElement RuntimeQueryElement = new Container("linux/amd64", new[] { - new From("php:8.2-apache-buster", new[] - { - new WithExec(new []{"apt-get", "update" }, new [] - { - new WithExec(new []{"apt-get", "install", "--yes", "git-core" }, new [] - { - new WithExec(new []{"apt-get", "install", "--yes", "zip" }, new[] - { - new WithExec(new []{"apt-get", "install", "--yes", "curl" }, new[] - { - new WithExec(new []{"docker-php-ext-install", "pdo", "pdo_mysql", "mysqli" }, new[] - { - new WithExec(new []{"sh", "-c", "sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf" }, new[] - { - new WithExec(new []{"sh", "-c", "sed -ri -e 's!/var/www/!/var/www/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf" }, new[] - { - new WithExec(new []{"a2enmod", "rewrite" }, new GraphQLElement[]{new("stdout"), new("stderr") }) - }) - }) - }) - }) - }) - }) - }) - }) - }); - - public static ContainerBuilder ContainerBuilder = new ContainerBuilder - { - Platform = "linux/amd64", - BaseImage = "php:8.2-apache-buster", - Commands = new() - { - new[]{"apt-get", "update"}, - new[]{"apt-get", "install", "--yes", "git-core"}, - new[]{"apt-get", "install", "--yes", "zip"}, - new[]{"apt-get", "install", "--yes", "curl"}, - new[]{"docker-php-ext-install", "pdo", "pdo_mysql", "mysqli"}, - new[]{"sh", "-c", "sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf"}, - new[]{"sh", "-c", "sed -ri -e 's!/var/www/!/var/www/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf"}, - new[]{"a2enmod", "rewrite" }, - } - }; -} diff --git a/sdk/dotnet/Tests/IntegrationTests/Usings.cs b/sdk/dotnet/Tests/IntegrationTests/Usings.cs deleted file mode 100644 index cefced49698..00000000000 --- a/sdk/dotnet/Tests/IntegrationTests/Usings.cs +++ /dev/null @@ -1 +0,0 @@ -global using NUnit.Framework; \ No newline at end of file