Skip to content

Commit ec7a460

Browse files
committed
Start of policy
1 parent 61f95be commit ec7a460

30 files changed

+2281
-34
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
component: sdk/policy
2+
kind: Improvements
3+
body: Initial version of Policy As Code
4+
time: 2025-06-12T15:26:39.284198744+01:00
5+
custom:
6+
PR: "645"

.changie.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ components:
1717
- sdk
1818
- sdk/auto
1919
- sdk/provider
20+
- sdk/policy
2021
- sdk/converter
2122
- runtime
2223
changeFormat: '- [{{.Component}}] {{.Body}} [#{{.Custom.PR}}](https://github.com/pulumi/pulumi-dotnet/pull/{{.Custom.PR}})'

pulumi-language-dotnet/go.mod

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@ replace github.com/atotto/clipboard => github.com/tgummerer/clipboard v0.0.0-202
1212

1313
require (
1414
github.com/blang/semver v3.5.1+incompatible
15+
github.com/deckarep/golang-set/v2 v2.5.0
1516
github.com/pkg/errors v0.9.1
16-
github.com/pulumi/pulumi/pkg/v3 v3.175.0
17-
github.com/pulumi/pulumi/sdk/v3 v3.175.0
17+
github.com/pulumi/pulumi/pkg/v3 v3.176.0
18+
github.com/pulumi/pulumi/sdk/v3 v3.176.0
1819
github.com/stretchr/testify v1.10.0
19-
google.golang.org/grpc v1.67.1
20+
google.golang.org/grpc v1.72.1
2021
google.golang.org/protobuf v1.36.6
2122
)
2223

@@ -41,7 +42,6 @@ require (
4142
github.com/cloudflare/circl v1.3.8 // indirect
4243
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
4344
github.com/davecgh/go-spew v1.1.1 // indirect
44-
github.com/deckarep/golang-set/v2 v2.5.0 // indirect
4545
github.com/djherbis/times v1.6.0 // indirect
4646
github.com/edsrzf/mmap-go v1.1.0 // indirect
4747
github.com/emirpasic/gods v1.18.1 // indirect
@@ -80,7 +80,7 @@ require (
8080
github.com/pulumi/esc v0.14.2 // indirect
8181
github.com/pulumi/inflector v0.1.1 // indirect
8282
github.com/rivo/uniseg v0.4.7 // indirect
83-
github.com/rogpeppe/go-internal v1.12.0 // indirect
83+
github.com/rogpeppe/go-internal v1.13.1 // indirect
8484
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect
8585
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect
8686
github.com/segmentio/asm v1.1.3 // indirect
@@ -106,7 +106,7 @@ require (
106106
golang.org/x/term v0.32.0 // indirect
107107
golang.org/x/text v0.25.0 // indirect
108108
golang.org/x/tools v0.23.0 // indirect
109-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
109+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 // indirect
110110
gopkg.in/warnings.v0 v0.1.2 // indirect
111111
gopkg.in/yaml.v3 v3.0.1 // indirect
112112
lukechampine.com/frand v1.4.2 // indirect

pulumi-language-dotnet/go.sum

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf
2525
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
2626
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
2727
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
28-
cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY=
29-
cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY=
28+
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
29+
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
3030
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
3131
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
3232
cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
@@ -191,8 +191,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
191191
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
192192
github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY=
193193
github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
194-
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
195-
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
194+
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
195+
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
196196
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
197197
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
198198
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
@@ -395,16 +395,16 @@ github.com/pulumi/esc v0.14.2 h1:xHpjJXzKs1hk/QPpgwe1Rmif3VWA0QcZ7jDvTFYX/jM=
395395
github.com/pulumi/esc v0.14.2/go.mod h1:0dNzCWIiRUmdfFrhHdeBzU4GiDPBhSfpeWDNApZwZ08=
396396
github.com/pulumi/inflector v0.1.1 h1:dvlxlWtXwOJTUUtcYDvwnl6Mpg33prhK+7mzeF+SobA=
397397
github.com/pulumi/inflector v0.1.1/go.mod h1:HUFCjcPTz96YtTuUlwG3i3EZG4WlniBvR9bd+iJxCUY=
398-
github.com/pulumi/pulumi/pkg/v3 v3.175.0 h1:MsL2cnpGWivS/DLZ7MbJr0zMNg4P+pUprCEXvGoKBd4=
399-
github.com/pulumi/pulumi/pkg/v3 v3.175.0/go.mod h1:neGNOTNMYSGUrh/L8kiAgowHRoB/kMmmutPo8WcLzM4=
400-
github.com/pulumi/pulumi/sdk/v3 v3.175.0 h1:vANFQOpWjJFCuVBim7AfOM3hHnNHgjJ8NlVwG1qezd4=
401-
github.com/pulumi/pulumi/sdk/v3 v3.175.0/go.mod h1:AD2BrIxFG4wdCLCFODrOasXhURwrD/8hHrwBcjzyU9Y=
398+
github.com/pulumi/pulumi/pkg/v3 v3.176.0 h1:akXBEYuOJt2SzAqTIwqaOV+IjDOAxLG4R6tgUYJuSOA=
399+
github.com/pulumi/pulumi/pkg/v3 v3.176.0/go.mod h1:WDH86DPa9LEv3etXiDInXtDYH80TzrGlBZKouKOIiRo=
400+
github.com/pulumi/pulumi/sdk/v3 v3.176.0 h1:CjzJ/59O85O492XRvly61F2frc/YO/LNpt9hytGer+k=
401+
github.com/pulumi/pulumi/sdk/v3 v3.176.0/go.mod h1:AD2BrIxFG4wdCLCFODrOasXhURwrD/8hHrwBcjzyU9Y=
402402
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
403403
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
404404
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
405405
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
406-
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
407-
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
406+
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
407+
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
408408
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
409409
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
410410
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
@@ -472,16 +472,22 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
472472
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
473473
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
474474
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
475+
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
476+
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
475477
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
476478
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
477479
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
478480
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
479-
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
480-
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
481-
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
482-
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
483-
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
484-
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
481+
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
482+
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
483+
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
484+
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
485+
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
486+
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
487+
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
488+
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
489+
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
490+
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
485491
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
486492
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
487493
gocloud.dev v0.37.0 h1:XF1rN6R0qZI/9DYjN16Uy0durAmSlf58DHOcb28GPro=
@@ -579,8 +585,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
579585
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
580586
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
581587
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
582-
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
583-
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
588+
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
589+
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
584590
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
585591
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
586592
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -781,10 +787,10 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D
781787
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
782788
google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 h1:ImUcDPHjTrAqNhlOkSocDLfG9rrNHH7w7uoKWPaWZ8s=
783789
google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7/go.mod h1:/3XmxOjePkvmKrHuBy4zNFw7IzxJXtAgdpXi8Ll990U=
784-
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8=
785-
google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo=
786-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
787-
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
790+
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237 h1:Kog3KlB4xevJlAcbbbzPfRG0+X9fdoGM+UBRKVz6Wr0=
791+
google.golang.org/genproto/googleapis/api v0.0.0-20250519155744-55703ea1f237/go.mod h1:ezi0AVyMKDWy5xAncvjLWH7UcLBB5n7y2fQ8MzjJcto=
792+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237 h1:cJfm9zPbe1e873mHJzmQ1nwVEeRDU/T1wXDK2kUSU34=
793+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
788794
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
789795
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
790796
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -801,8 +807,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
801807
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
802808
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
803809
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
804-
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
805-
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
810+
google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
811+
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
806812
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
807813
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
808814
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

pulumi-language-dotnet/language_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"os"
2323
"os/exec"
2424
"path/filepath"
25-
"strings"
2625
"sync"
2726
"testing"
2827

@@ -221,6 +220,13 @@ var programOverrides = map[string]*testingrpc.PrepareLanguageTestsRequest_Progra
221220

222221
func TestLanguage(t *testing.T) {
223222
t.Parallel()
223+
224+
// We need nuget caches cleared when running these tests otherwise nuget won't pick up the newly built
225+
// SDKs that were building as part of testing.
226+
cmd := exec.Command("dotnet", "nuget", "locals", "all", "--clear")
227+
output, err := cmd.CombinedOutput()
228+
require.NoError(t, err, "failed to clear nuget caches: %s", output)
229+
224230
engineAddress, engine := runTestingHost(t)
225231

226232
tests, err := engine.GetLanguageTests(context.Background(), &testingrpc.GetLanguageTestsRequest{})
@@ -251,6 +257,7 @@ func TestLanguage(t *testing.T) {
251257
TemporaryDirectory: rootDir,
252258
SnapshotDirectory: snapshotDir,
253259
CoreSdkDirectory: "../sdk/Pulumi",
260+
PolicyPackDirectory: "testdata/policies",
254261
SnapshotEdits: []*testingrpc.PrepareLanguageTestsRequest_Replacement{
255262
{
256263
Pattern: rootDir + "/artifacts",
@@ -268,9 +275,6 @@ func TestLanguage(t *testing.T) {
268275
if expected, ok := expectedFailures[tt]; ok {
269276
t.Skipf("test %s is expected to fail: %s", tt, expected)
270277
}
271-
if strings.HasPrefix(tt, "policy-") {
272-
t.Skipf("dotnet doesn't support policy tests yet: %s", tt)
273-
}
274278

275279
result, err := engine.RunLanguageTest(context.Background(), &testingrpc.RunLanguageTestRequest{
276280
Token: prepare.Token,

pulumi-language-dotnet/main.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,25 @@ import (
1818
"bytes"
1919
"context"
2020
"encoding/json"
21+
"encoding/xml"
2122
"flag"
2223
"fmt"
2324
"io"
25+
"log"
2426
"math/rand"
2527
"os"
2628
"os/exec"
2729
"os/signal"
30+
"path"
2831
"path/filepath"
32+
"sort"
2933
"strconv"
3034
"strings"
3135
"syscall"
3236
"time"
3337

3438
"github.com/blang/semver"
39+
mapset "github.com/deckarep/golang-set/v2"
3540
"github.com/pkg/errors"
3641
"github.com/pulumi/pulumi-dotnet/pulumi-language-dotnet/v3/version"
3742
dotnetcodegen "github.com/pulumi/pulumi/pkg/v3/codegen/dotnet"
@@ -1107,6 +1112,9 @@ func (host *dotnetLanguageHost) RunPlugin(
11071112
cmd.Env = append(req.Env, "PULUMI_ATTACH_DEBUGGER=true")
11081113
}
11091114
cmd.Stdout, cmd.Stderr = stdout, stderr
1115+
// wait a second for the plugin to shutdown, dotnet doesn't seem to close of IO pipes so without WaitDelay
1116+
// set we'd block forever in Wait.
1117+
cmd.WaitDelay = time.Second
11101118
if err := cmd.Start(); err != nil {
11111119
return err
11121120
}
@@ -1380,3 +1388,148 @@ func (host *dotnetLanguageHost) GenerateProgram(
13801388
Diagnostics: rpcDiagnostics,
13811389
}, nil
13821390
}
1391+
1392+
func extractNugetPackageNameAndVersion(nugetFilePath string) (string, string, bool) {
1393+
filename := filepath.Base(nugetFilePath)
1394+
parts := strings.Split(filename, ".")
1395+
if len(parts) >= 5 {
1396+
patch := parts[len(parts)-2]
1397+
minor := parts[len(parts)-3]
1398+
major := parts[len(parts)-4]
1399+
version := fmt.Sprintf("%s.%s.%s", major, minor, patch)
1400+
pkg := strings.TrimSuffix(filename, fmt.Sprintf(".%s.nupkg", version))
1401+
return pkg, version, true
1402+
}
1403+
1404+
return "", "", false
1405+
}
1406+
1407+
func (host *dotnetLanguageHost) Link(
1408+
ctx context.Context, req *pulumirpc.LinkRequest,
1409+
) (*pulumirpc.LinkResponse, error) {
1410+
1411+
// Find all the local dependency folders
1412+
folders := mapset.NewSet[string]()
1413+
artifacts := map[string]struct {
1414+
name string
1415+
version string
1416+
}{}
1417+
for _, dep := range req.LocalDependencies {
1418+
folders.Add(path.Dir(dep))
1419+
name, version, ok := extractNugetPackageNameAndVersion(dep)
1420+
if ok {
1421+
artifacts[dep] = struct {
1422+
name string
1423+
version string
1424+
}{name: name, version: version}
1425+
} else {
1426+
logging.V(3).Infof("warning: could not extract package name and version from %s", dep)
1427+
}
1428+
}
1429+
1430+
restoreSources := folders.ToSlice()
1431+
sort.Strings(restoreSources)
1432+
1433+
// Look for a csproj file in the program directory
1434+
programDirectory := req.Info.ProgramDirectory
1435+
csprojFile := ""
1436+
err := filepath.Walk(programDirectory, func(path string, info os.FileInfo, err error) error {
1437+
if err != nil {
1438+
return err
1439+
}
1440+
if !info.IsDir() && filepath.Ext(path) == ".csproj" {
1441+
csprojFile = path
1442+
}
1443+
return nil
1444+
})
1445+
if err != nil {
1446+
return nil, fmt.Errorf("failed to find csproj file: %w", err)
1447+
}
1448+
1449+
csproj, err := os.Open(csprojFile)
1450+
if err != nil {
1451+
return nil, fmt.Errorf("failed to open csproj file: %w", err)
1452+
}
1453+
1454+
// Edit the XML to add the restorsources
1455+
var buf bytes.Buffer
1456+
decoder := xml.NewDecoder(csproj)
1457+
encoder := xml.NewEncoder(&buf)
1458+
1459+
restoreWritten := false
1460+
for {
1461+
token, err := decoder.Token()
1462+
if err == io.EOF {
1463+
break
1464+
}
1465+
if err != nil {
1466+
return nil, fmt.Errorf("error reading csproj token: %w", err)
1467+
}
1468+
1469+
inPropertyGroup := false
1470+
switch v := token.(type) {
1471+
case xml.StartElement:
1472+
if v.Name.Local == "PropertyGroup" {
1473+
inPropertyGroup = true
1474+
}
1475+
if v.Name.Local == "PackageReference" {
1476+
// If this is a package reference, check if it matches any of the local dependencies
1477+
attrs := make(map[string]string)
1478+
for _, attr := range v.Attr {
1479+
attrs[attr.Name.Local] = attr.Value
1480+
}
1481+
name := attrs["Include"]
1482+
1483+
// Reset the version to the local one
1484+
version := attrs["Version"]
1485+
for _, artifact := range artifacts {
1486+
if artifact.name == name {
1487+
version = artifact.version
1488+
break
1489+
}
1490+
}
1491+
attrs["Version"] = version
1492+
1493+
// Rebuild the start element with the updated attributes
1494+
v.Attr = make([]xml.Attr, 0, len(attrs))
1495+
for k, val := range attrs {
1496+
v.Attr = append(v.Attr, xml.Attr{
1497+
Name: xml.Name{Local: k},
1498+
Value: val,
1499+
})
1500+
}
1501+
token = v
1502+
}
1503+
}
1504+
1505+
if err := encoder.EncodeToken(xml.CopyToken(token)); err != nil {
1506+
log.Fatal(err)
1507+
}
1508+
1509+
// Once we've found the first PropertyGroup, we can add the RestoreSources element
1510+
if inPropertyGroup && !restoreWritten {
1511+
encoder.EncodeElement(
1512+
fmt.Sprintf("%s;$(RestoreSources)", strings.Join(restoreSources, ";")),
1513+
xml.StartElement{
1514+
Name: xml.Name{Local: "RestoreSources"},
1515+
},
1516+
)
1517+
restoreWritten = true
1518+
}
1519+
}
1520+
1521+
// must call flush, otherwise some elements will be missing
1522+
if err := encoder.Flush(); err != nil {
1523+
log.Fatal(err)
1524+
}
1525+
1526+
// Write the modified XML back to the csproj file
1527+
if err := csproj.Close(); err != nil {
1528+
logging.V(3).Infof("error closing csproj file: %v\n", err)
1529+
}
1530+
if err := os.WriteFile(csprojFile, buf.Bytes(), 0o644); err != nil {
1531+
return nil, fmt.Errorf("failed to write csproj file: %w", err)
1532+
}
1533+
1534+
return &pulumirpc.LinkResponse{}, nil
1535+
}

0 commit comments

Comments
 (0)