diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index da3c625..896afe9 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -2,17 +2,35 @@ "version": 1, "isRoot": true, "tools": { - "fake-cli": { - "version": "5.20.4", + "dotnet-reportgenerator-globaltool": { + "version": "5.1.18", "commands": [ - "fake" + "reportgenerator" ] }, "paket": { - "version": "6.0.6", + "version": "8.0.3", "commands": [ "paket" ] + }, + "fsharp-analyzers": { + "version": "0.11.0", + "commands": [ + "fsharp-analyzers" + ] + }, + "fantomas": { + "version": "6.0.1", + "commands": [ + "fantomas" + ] + }, + "fsdocs-tool": { + "version": "18.1.0", + "commands": [ + "fsdocs" + ] } } } \ No newline at end of file diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..96c07a3 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,17 @@ +# [Choice] Debian version (use bullseye on local arm64/Apple Silicon): bookworm, bullseye, buster +ARG VARIANT="bookworm" +FROM buildpack-deps:${VARIANT}-curl + + +ENV \ + # Enable detection of running in a container + DOTNET_RUNNING_IN_CONTAINER=true \ + DOTNET_ROOT=/usr/share/dotnet/ \ + DOTNET_NOLOGO=true \ + DOTNET_CLI_TELEMETRY_OPTOUT=false\ + DOTNET_USE_POLLING_FILE_WATCHER=true + + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..3f27ab2 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,73 @@ +{ + "name": "dotnet", + // Set the build context one level higher so we can grab metadata like global.json + "context": "..", + "dockerFile": "Dockerfile", + "forwardPorts": [ + 0 + ], + "features": { + // https://github.com/devcontainers/features/blob/main/src/common-utils/README.md + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": true, + "installOhMyZshConfig": true, + "configureZshAsDefaultShell": true, + "username": "vscode", + "userUid": "1000", + "userGid": "1000", + "upgradePackages": true + }, + // https://github.com/devcontainers/features/blob/main/src/github-cli/README.md + "ghcr.io/devcontainers/features/github-cli:1": {}, + // https://github.com/devcontainers-contrib/features/blob/main/src/starship/README.md + "ghcr.io/devcontainers-contrib/features/starship:1": {}, + // https://github.com/devcontainers/features/blob/main/src/dotnet/README.md + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "7.0", + "additionalVersions": "6.0" + } + }, + "overrideFeatureInstallOrder": [ + "ghcr.io/devcontainers/features/common-utils", + "ghcr.io/devcontainers/features/github-cli", + "ghcr.io/devcontainers-contrib/features/starship", + "ghcr.io/devcontainers/features/dotnet" + ], + "customizations": { + "vscode": { + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-dotnettools.csharp", + "Ionide.Ionide-fsharp", + "tintoy.msbuild-project-tools", + "ionide.ionide-paket", + "usernamehw.errorlens", + "alefragnani.Bookmarks", + "oderwat.indent-rainbow", + "vscode-icons-team.vscode-icons", + "EditorConfig.EditorConfig", + "ms-azuretools.vscode-docker", + "GitHub.vscode-pull-request-github", + "github.vscode-github-actions" + ], + "settings": { + "terminal.integrated.defaultProfile.linux": "zsh", + "csharp.suppressDotnetInstallWarning": true + } + } + }, + "remoteUser": "vscode", + "containerUser": "vscode", + "containerEnv": { + // Expose the local environment variable to the container + // They are used for releasing and publishing from the container + "GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}" + }, + "onCreateCommand": { + "enable-starship": "echo 'eval \"$(starship init zsh)\"' >> ~/.zshrc" + }, + "postAttachCommand": { + "restore": "dotnet tool restore && dotnet restore" + }, + "waitFor": "updateContentCommand" +} \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..87474da --- /dev/null +++ b/.editorconfig @@ -0,0 +1,70 @@ +# EditorConfig is awesome: +http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Default settings: +# A newline ending every file +# Use 4 spaces as indentation +[*] +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true +end_of_line = lf + +[*.{fs,fsi,fsx,config}] +# https://fsprojects.github.io/fantomas/docs/end-users/Configuration.html +charset = utf-8 +trim_trailing_whitespace = true +max_line_length=100 +fsharp_multiline_bracket_style = stroustrup +fsharp_keep_max_number_of_blank_lines=2 +fsharp_max_array_or_list_number_of_items=1 +fsharp_array_or_list_multiline_formatter=number_of_items +fsharp_max_infix_operator_expression=10 +fsharp_multi_line_lambda_closing_newline=true + +# Visual Studio Solution Files +[*.sln] +indent_style = tab + +# XML project files +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj,sfproj}] +indent_size = 2 + +# XML config files +[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] +indent_size = 2 + +# Markdown Files +[*.{md,mdx}] +trim_trailing_whitespace = false + +# Bash Files +[*.{sh}] +end_of_line = lf + +# Batch Files +[*.{cmd,bat}] +end_of_line = crlf + +# Powershell Files +[*.{ps1, psm1}] +end_of_line = crlf + +# Paket files +[paket.*] +trim_trailing_whitespace = true +indent_size = 2 + +[*.paket.references] +trim_trailing_whitespace = true +indent_size = 2 + + +# YAML Files +[*.{yml,yaml}] +indent_size = 2 +indent_style = space diff --git a/.fantomasignore b/.fantomasignore new file mode 100644 index 0000000..4660636 --- /dev/null +++ b/.fantomasignore @@ -0,0 +1,5 @@ +# Ignore AssemblyInfo files +AssemblyInfo.fs + +# TODO: clean up this code and remove this +src/Pulumi.FSharp.Myriad/Modules.fs \ No newline at end of file diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..9c8817e --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,6 @@ +# This file contains a list of git hashes of revisions to be ignored by git +# These revisions are considered "unimportant" in +# that they are unlikely to be what you are interested in when blaming. +# Like formatting with Fantomas +# https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view +# Add formatting commits here diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..cb6f883 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,27 @@ +# Auto detect text files +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp text=auto eol=lf +*.vb diff=csharp text=auto eol=lf +*.fs diff=csharp text=auto eol=lf +*.fsi diff=csharp text=auto eol=lf +*.fsx diff=csharp text=auto eol=lf +*.sln text eol=crlf merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union +*.sh text eol=lf + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..02ca9be --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,31 @@ +## Description + +Please insert a description of your problem or question. + +## Error messages, screenshots + +Please add any error logs or screenshots if available. + +## Failing test, failing GitHub repo, or reproduction steps + +Please add either a failing test, a GitHub repo of the problem or detailed reproduction steps. + +## Expected Behavior + +Please define what you would expect the behavior to be like. + +## Known workarounds + +Please provide a description of any known workarounds. + +## Other information + +* Operating System: + - [ ] windows [insert version here] + - [ ] macOs [insert version] + - [ ] linux [insert flavor/version here] +* Platform + - [ ] dotnet core + - [ ] dotnet full + - [ ] mono +* Branch or release version: diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..b735373 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..066b2d9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..ebdd8d1 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,25 @@ +## Proposed Changes + +Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue. + +## Types of changes + +What types of changes does your code introduce to Pulumi.FSharp.Extensions? +_Put an `x` in the boxes that apply_ + +- [ ] Bugfix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) + + +## Checklist + +_Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._ + +- [ ] Build and tests pass locally +- [ ] I have added tests that prove my fix is effective or that my feature works (if appropriate) +- [ ] I have added necessary documentation (if appropriate) + +## Further comments + +If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 0000000..29c7521 --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,24 @@ +name: .NET Build and Test + +on: + pull_request: {} +env: + CONFIGURATION: Debug +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup necessary dotnet SDKs + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + dotnet-version: | + 8.x + - name: Build providers + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FAKE_DETAILED_ERRORS: true + ENABLE_COVERAGE: false + run: | + ./build.sh BuildProviders \ No newline at end of file diff --git a/.github/workflows/paket-autoupdate.yml b/.github/workflows/paket-autoupdate.yml new file mode 100644 index 0000000..08ae74f --- /dev/null +++ b/.github/workflows/paket-autoupdate.yml @@ -0,0 +1,33 @@ +name: Paket Update + +on: + workflow_dispatch: {} + schedule: + - cron: "0 */4 * * *" + +jobs: + paket-update: + permissions: + packages: read + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup necessary dotnet SDKs + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + dotnet-version: | + 8.x + # https://github.com/orgs/community/discussions/26560#discussioncomment-3531273 + - name: Configure Git + run: | + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config user.name "github-actions[bot]" + - name: Paket Update + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FAKE_DETAILED_ERRORS: true + run: | + ./build.sh PaketUpdate diff --git a/.github/workflows/publish-providers.yml b/.github/workflows/publish-providers.yml new file mode 100644 index 0000000..debb4f5 --- /dev/null +++ b/.github/workflows/publish-providers.yml @@ -0,0 +1,32 @@ +name: .NET Publish Providers + +on: + push: + branches: + - main + +env: + CONFIGURATION: Release +jobs: + build: + permissions: + packages: write + environment: + name: nuget + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup necessary dotnet SDKs + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + dotnet-version: | + 8.x + - name: Publish providers + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NUGET_TOKEN: ${{ secrets.GITHUB_TOKEN }} # this is intentional — we publish to github packages + FAKE_DETAILED_ERRORS: true + ENABLE_COVERAGE: false # AltCover doesn't work with Release builds, reports lower coverage than actual + run: | + ./build.sh PublishProviders diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..08c1de0 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,34 @@ +name: .NET Publish Extensions + +on: + push: + branches: + - main + paths: + - src/** +env: + CONFIGURATION: Release +jobs: + build: + # Sets permissions of the GITHUB_TOKEN to allow release creating + permissions: + packages: write + environment: + name: nuget + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup necessary dotnet SDKs + uses: actions/setup-dotnet@v4 + with: + global-json-file: global.json + dotnet-version: | + 8.x + - name: Publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NUGET_TOKEN: ${{ secrets.GITHUB_TOKEN }} # this is intentional — we publish to github packages + FAKE_DETAILED_ERRORS: true + ENABLE_COVERAGE: false # AltCover doesn't work with Release builds, reports lower coverage than actual + run: | + ./build.sh Publish diff --git a/.gitignore b/.gitignore index a8487f0..8b011f7 100644 --- a/.gitignore +++ b/.gitignore @@ -351,6 +351,17 @@ MigrationBackup/ .idea/ -/TODO -/Generated.fs -Pulumi.FSharp.Extensions.vault.json \ No newline at end of file + +# Paket tool store +.paket/.store +.paket/paket + +# fsdocs generated +tmp/ +temp/ +.fsdocs +docs/ + +providers/Pulumi.FSharp.*/*.json +providers/Pulumi.FSharp.*/Generated.fs +.DS_Store diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets new file mode 100644 index 0000000..c66062b --- /dev/null +++ b/.paket/Paket.Restore.targets @@ -0,0 +1,560 @@ + + + + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + $(MSBuildVersion) + 15.0.0 + false + true + + true + $(MSBuildThisFileDirectory) + $(MSBuildThisFileDirectory)..\ + $(PaketRootPath)paket-files\paket.restore.cached + $(PaketRootPath)paket.lock + classic + proj + assembly + native + /Library/Frameworks/Mono.framework/Commands/mono + mono + + + $(PaketRootPath)paket.bootstrapper.exe + $(PaketToolsPath)paket.bootstrapper.exe + $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ + + "$(PaketBootStrapperExePath)" + $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" + + + + + true + true + + + True + + + False + + $(BaseIntermediateOutputPath.TrimEnd('\').TrimEnd('\/')) + + + + + + + + + $(PaketRootPath)paket + $(PaketToolsPath)paket + + + + + + $(PaketRootPath)paket.exe + $(PaketToolsPath)paket.exe + + + + + + <_DotnetToolsJson Condition="Exists('$(PaketRootPath)/.config/dotnet-tools.json')">$([System.IO.File]::ReadAllText("$(PaketRootPath)/.config/dotnet-tools.json")) + <_ConfigContainsPaket Condition=" '$(_DotnetToolsJson)' != ''">$(_DotnetToolsJson.Contains('"paket"')) + <_ConfigContainsPaket Condition=" '$(_ConfigContainsPaket)' == ''">false + + + + + + + + + + + <_PaketCommand>dotnet paket + + + + + + $(PaketToolsPath)paket + $(PaketBootStrapperExeDir)paket + + + paket + + + + + <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) + <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(_PaketExeExtension)' == '.dll' ">dotnet "$(PaketExePath)" + <_PaketCommand Condition=" '$(_PaketCommand)' == '' AND '$(OS)' != 'Windows_NT' AND '$(_PaketExeExtension)' == '.exe' ">$(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" + <_PaketCommand Condition=" '$(_PaketCommand)' == '' ">"$(PaketExePath)" + + + + + + + + + + + + + + + + + + + + + true + $(NoWarn);NU1603;NU1604;NU1605;NU1608 + false + true + + + + + + + + + $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) + + + + + + + $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[0].Replace(`"`, ``).Replace(` `, ``)) + $([System.Text.RegularExpressions.Regex]::Split(`%(Identity)`, `": "`)[1].Replace(`"`, ``).Replace(` `, ``)) + + + + + %(PaketRestoreCachedKeyValue.Value) + %(PaketRestoreCachedKeyValue.Value) + + + + + true + false + true + + + + + true + + + + + + + + + + + + + + + + + + + $(PaketIntermediateOutputPath)\$(MSBuildProjectFile).paket.references.cached + + $(MSBuildProjectFullPath).paket.references + + $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references + + $(MSBuildProjectDirectory)\paket.references + + false + true + true + references-file-or-cache-not-found + + + + + $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)')) + $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)')) + references-file + false + + + + + false + + + + + true + target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths) + + + + + + + + + + + false + true + + + + + + + + + + + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[8]) + + + %(PaketReferencesFileLinesInfo.PackageVersion) + All + runtime + $(ExcludeAssets);contentFiles + $(ExcludeAssets);build;buildMultitargeting;buildTransitive + %(PaketReferencesFileLinesInfo.Aliases) + true + true + + + + + + $(PaketIntermediateOutputPath)/$(MSBuildProjectFile).paket.clitools + + + + + + + + + $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0]) + $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1]) + + + %(PaketCliToolFileLinesInfo.PackageVersion) + + + + + + + + + + false + + + + + + <_NuspecFilesNewLocation Include="$(PaketIntermediateOutputPath)\$(Configuration)\*.nuspec"/> + + + + + + $(MSBuildProjectDirectory)/$(MSBuildProjectFile) + true + false + true + false + true + false + true + false + true + false + true + $(PaketIntermediateOutputPath)\$(Configuration) + $(PaketIntermediateOutputPath) + + + + <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.$(PackageVersion.Split(`+`)[0]).nuspec"/> + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d566ef1 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,9 @@ +{ + "recommendations": [ + "ionide.ionide-paket", + "ionide.ionide-fsharp", + "ionide.ionide-fake", + "ms-dotnettools.csharp", + "editorConfig.editorConfig" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..d677c61 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,41 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "inputs": [ + { + "id": "provider", + "description": "Pulumi provider name", + "type": "pickString", + "options": [ + "Auth0", + "Aws", + "Azure", + "AzureAD", + "AzureNative", + "AzureNativeV2", + "Command", + "Docker", + "DigitalOcean", + "Gcp", + "Kubernetes", + "Random", + "Tls"] + } + ], + "configurations": [ + { + "name": "Debug Myriad code generation", + "type": "coreclr", + "request": "launch", + "program": "${userHome}/.nuget/packages/myriad.sdk/0.8.1/tools/net6.0/any/Myriad.dll", + "args": ["--inputfile", "${workspaceFolder}/providers/Pulumi.FSharp.${input:provider}/Myriad.fs", "--outputfile", "${workspaceFolder}/providers/Pulumi.FSharp.${input:provider}/Generated.fs", "--plugin", "${workspaceFolder}/src/Pulumi.FSharp.Myriad/bin/Debug/net6.0/Pulumi.FSharp.Myriad.dll"], + "cwd": "${workspaceFolder}/providers/Pulumi.FSharp.${input:provider}/", + "stopAtEntry": true, + "justMyCode": true, + "console": "internalConsole" + }, + + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b98926a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "FSharp.fsacRuntime":"netcore", + "FSharp.enableAnalyzers": false, + "FSharp.analyzersPath": [ + "./packages/analyzers" + ] +} diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..2d27dfc --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,27 @@ + + + + + + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + Stefano d'Antonio (UnoSD), Cadence Agyirey (cagyirey) + f#, fsharp, pulumi, iac + https://github.com/cagyirey/Pulumi.FSharp.Extensions + false + LICENSE.md + README.md + git + https://github.com/cagyirey/Pulumi.FSharp.Extensions + + + false + + + + + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000..d0f9a53 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,27 @@ + + + + + <_BuildProjBaseIntermediateOutputPath>$(MSBuildThisFileDirectory)build/obj/ + <_DotnetToolManifestFile>$(MSBuildThisFileDirectory).config/dotnet-tools.json + <_DotnetToolRestoreOutputFile>$(_BuildProjBaseIntermediateOutputPath)/dotnet-tool-restore-$(NETCoreSdkVersion)-$(OS) + <_DotnetFantomasOutputFile>$(BaseIntermediateOutputPath)dotnet-fantomas-msbuild-$(NETCoreSdkVersion)-$(OS) + + + + + + + + + + + + + + + + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..96c07a3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# [Choice] Debian version (use bullseye on local arm64/Apple Silicon): bookworm, bullseye, buster +ARG VARIANT="bookworm" +FROM buildpack-deps:${VARIANT}-curl + + +ENV \ + # Enable detection of running in a container + DOTNET_RUNNING_IN_CONTAINER=true \ + DOTNET_ROOT=/usr/share/dotnet/ \ + DOTNET_NOLOGO=true \ + DOTNET_CLI_TELEMETRY_OPTOUT=false\ + DOTNET_USE_POLLING_FILE_WATCHER=true + + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends diff --git a/FAKE.yml b/FAKE.yml deleted file mode 100644 index b6a46c1..0000000 --- a/FAKE.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: $(Rev:r) - -# Set the pipeline variable `provider` to a provider E.G. `Azure` `AzureAD` `Aws` `Kubernetes` - -# Create a secure file `Pulumi.FSharp.Extensions.vault.json` -# with the following content: -# { -# "values": [ -# { -# "secret": false, -# "value": "", -# "name": "nuGetApiKey" -# } -# ] -# } - -trigger: - branches: - include: - - master - paths: - include: - - Pulumi.FSharp.Myriad/* - -pool: #GitHubRunners - vmImage: ubuntu-latest - -steps: -- task: DotNetCoreCLI@2 - displayName: Install FAKE - inputs: - command: custom - custom: tool - arguments: restore - -- task: DownloadSecureFile@1 - name: FakeVaultFile - displayName: Download FAKE Vault file - inputs: - secureFile: Pulumi.FSharp.Extensions.vault.json - -- task: DotNetCoreCLI@2 - displayName: Run FAKE - env: - FAKE_DETAILED_ERRORS: true - inputs: - command: custom - custom: fake - arguments: run \ No newline at end of file diff --git a/LICENSE b/LICENSE.md similarity index 67% rename from LICENSE rename to LICENSE.md index d159169..5d8ae11 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,65 +1,7 @@ GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. This License applies to any program or other work which contains + 1. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" @@ -276,64 +218,3 @@ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/Main.fs b/Main.fs new file mode 100644 index 0000000..85e2468 --- /dev/null +++ b/Main.fs @@ -0,0 +1,9 @@ +namespace Pulumi.FSharp.Extensions.Tests + +module ExpectoTemplate = + + open Expecto + + [] + let main argv = + Tests.runTestsInAssembly defaultConfig argv diff --git a/Pulumi.FSharp.Aws/Myriad.fs b/Pulumi.FSharp.Aws/Myriad.fs deleted file mode 100644 index 72521b5..0000000 --- a/Pulumi.FSharp.Aws/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private Aws - -//module Force = let private nonce = 16490 \ No newline at end of file diff --git a/Pulumi.FSharp.Aws/Pulumi.FSharp.Aws.fsproj b/Pulumi.FSharp.Aws/Pulumi.FSharp.Aws.fsproj deleted file mode 100644 index aa23bc4..0000000 --- a/Pulumi.FSharp.Aws/Pulumi.FSharp.Aws.fsproj +++ /dev/null @@ -1,58 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2020 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi aws - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - - diff --git a/Pulumi.FSharp.Azure/Myriad.fs b/Pulumi.FSharp.Azure/Myriad.fs deleted file mode 100644 index adc311d..0000000 --- a/Pulumi.FSharp.Azure/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private Azure - -//module Force = let private nonce = 965 \ No newline at end of file diff --git a/Pulumi.FSharp.Azure/Pulumi.FSharp.Azure.fsproj b/Pulumi.FSharp.Azure/Pulumi.FSharp.Azure.fsproj deleted file mode 100644 index 9bf2874..0000000 --- a/Pulumi.FSharp.Azure/Pulumi.FSharp.Azure.fsproj +++ /dev/null @@ -1,62 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2020 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi azure - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - - - - diff --git a/Pulumi.FSharp.AzureAD/Myriad.fs b/Pulumi.FSharp.AzureAD/Myriad.fs deleted file mode 100644 index 7440b95..0000000 --- a/Pulumi.FSharp.AzureAD/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private AzureAD - -//module Force = let private nonce = 27550 \ No newline at end of file diff --git a/Pulumi.FSharp.AzureAD/Pulumi.FSharp.AzureAD.fsproj b/Pulumi.FSharp.AzureAD/Pulumi.FSharp.AzureAD.fsproj deleted file mode 100644 index 45c6c49..0000000 --- a/Pulumi.FSharp.AzureAD/Pulumi.FSharp.AzureAD.fsproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2021 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi azuread - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - diff --git a/Pulumi.FSharp.AzureNative.Common/NamingConventions.fs b/Pulumi.FSharp.AzureNative.Common/NamingConventions.fs deleted file mode 100644 index 5c7fa74..0000000 --- a/Pulumi.FSharp.AzureNative.Common/NamingConventions.fs +++ /dev/null @@ -1,41 +0,0 @@ -module Pulumi.FSharp.NamingConventions.Azure - -open AzureLocations -open Pulumi - -// https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming - -module Region = - let private shorten (regionName : string) = - regionName.Replace("europe" , "eu" ) - .Replace("brazil" , "br" ) - .Replace("australia" , "au" ) - .Replace("switzerland" , "sw" ) - .Replace("pacific" , "pac") - .Replace("unitedstates", "us" ) - .Replace("central" , "c" ) - .Replace("north" , "n" ) - .Replace("south" , "s" ) - .Replace("east" , "e" ) - .Replace("west" , "w" ) - - let private configuredRegion = Config("azure-native").Get("location") - - let shortName = - locationsMap - |> Map.tryFind configuredRegion - |> Option.map(fun x -> x |> shorten) - |> Option.defaultWith (fun () -> failwith $"Missing or incorrect azure-native:location: {configuredRegion}") - -module Resource = - let private woa = - match Config().Get("workloadOrApplication") with - | null - | "" -> "" - | value -> $"{value}-" - - let name resourceType (instanceNumber : int) = - $"{resourceType}-{woa}{Deployment.Instance.StackName}-{Region.shortName}-{instanceNumber:D3}" - - let nameOne resourceType = - name resourceType 1 \ No newline at end of file diff --git a/Pulumi.FSharp.AzureNative.Common/Pulumi.FSharp.AzureNative.Common.fsproj b/Pulumi.FSharp.AzureNative.Common/Pulumi.FSharp.AzureNative.Common.fsproj deleted file mode 100644 index ff83af5..0000000 --- a/Pulumi.FSharp.AzureNative.Common/Pulumi.FSharp.AzureNative.Common.fsproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net6.0 - true - - - - - - - - - - - - diff --git a/Pulumi.FSharp.AzureNative/Myriad.fs b/Pulumi.FSharp.AzureNative/Myriad.fs deleted file mode 100644 index 6cda004..0000000 --- a/Pulumi.FSharp.AzureNative/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private AzureNative - -module Force = let private nonce = 1738045662 \ No newline at end of file diff --git a/Pulumi.FSharp.AzureNative/Pulumi.FSharp.AzureNative.fsproj b/Pulumi.FSharp.AzureNative/Pulumi.FSharp.AzureNative.fsproj deleted file mode 100644 index 8a531b2..0000000 --- a/Pulumi.FSharp.AzureNative/Pulumi.FSharp.AzureNative.fsproj +++ /dev/null @@ -1,61 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2021 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi azure - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - - - diff --git a/Pulumi.FSharp.AzureNativeV2/Myriad.fs b/Pulumi.FSharp.AzureNativeV2/Myriad.fs deleted file mode 100644 index 28fb767..0000000 --- a/Pulumi.FSharp.AzureNativeV2/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private AzureNativeV2 - -module Force = let private nonce = 1827270720 \ No newline at end of file diff --git a/Pulumi.FSharp.AzureNativeV2/Pulumi.FSharp.AzureNativeV2.fsproj b/Pulumi.FSharp.AzureNativeV2/Pulumi.FSharp.AzureNativeV2.fsproj deleted file mode 100644 index c69af4b..0000000 --- a/Pulumi.FSharp.AzureNativeV2/Pulumi.FSharp.AzureNativeV2.fsproj +++ /dev/null @@ -1,59 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2021 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi azure - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - - - diff --git a/Pulumi.FSharp.Command/Myriad.fs b/Pulumi.FSharp.Command/Myriad.fs deleted file mode 100644 index e9ff8c9..0000000 --- a/Pulumi.FSharp.Command/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private Command - -module Force = let private nonce = 1734416139 \ No newline at end of file diff --git a/Pulumi.FSharp.Command/Pulumi.FSharp.Command.fsproj b/Pulumi.FSharp.Command/Pulumi.FSharp.Command.fsproj deleted file mode 100644 index 2d7edef..0000000 --- a/Pulumi.FSharp.Command/Pulumi.FSharp.Command.fsproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2021 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi command - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - diff --git a/Pulumi.FSharp.Command/command.0.0.3.json b/Pulumi.FSharp.Command/command.0.0.3.json deleted file mode 100644 index 1c4adb8..0000000 --- a/Pulumi.FSharp.Command/command.0.0.3.json +++ /dev/null @@ -1,286 +0,0 @@ -{ - "name": "command", - "displayName": "Command", - "description": "The Pulumi Command Provider enables you to execute commands and scripts either locally or remotely as part of the Pulumi resource model.", - "keywords": [ - "pulumi", - "command", - "category/utility", - "kind/native" - ], - "homepage": "https://pulumi.com", - "license": "Apache-2.0", - "repository": "https://github.com/pulumi/pulumi-command", - "publisher": "Pulumi", - "logoUrl": "https://raw.githubusercontent.com/pulumi/pulumi-command/master/assets/logo.svg", - "types": { - "command:remote:Connection": { - "type": "object", - "description": "Instructions for how to connect to a remote endpoint.", - "properties": { - "user": { - "type": "string", - "description": "The user that we should use for the connection.", - "default": "root" - }, - "password": { - "type": "string", - "description": "The password we should use for the connection." - }, - "host": { - "type": "string", - "description": "The address of the resource to connect to." - }, - "port": { - "type": "number", - "description": "The port to connect to.", - "default": 22 - }, - "privateKey": { - "type": "string", - "description": "The contents of an SSH key to use for the connection. This takes preference over the password if provided." - } - }, - "required": [ - "host" - ] - } - }, - "resources": { - "command:local:Command": { - "description": "A local command to be executed.\nThis command can be inserted into the life cycles of other resources using the\n`dependsOn` or `parent` resource options. A command is considered to have\nfailed when it finished with a non-zero exit code. This will fail the CRUD step\nof the `Command` resource.", - "properties": { - "interpreter": { - "description": "The program and arguments to run the command.\nFor example: `[\"/bin/sh\", \"-c\"]`", - "type": "array", - "items": { - "type": "string" - } - }, - "dir": { - "description": "The directory from which to run the command from. If `dir` does not exist, then\n`Command` will fail.", - "type": "string" - }, - "environment": { - "description": "Additional environment variables available to the command's process.", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "triggers": { - "type": "array", - "description": "Trigger replacements on changes to this input.", - "items": { - "$ref": "pulumi.json#/Any" - } - }, - "create": { - "type": "string", - "description": "The command to run on create." - }, - "delete": { - "type": "string", - "description": "The command to run on delete." - }, - "stdout": { - "description": "The standard output of the command's process", - "type": "string" - }, - "stderr": { - "description": "The standard error of the command's process", - "type": "string" - } - }, - "required": [ - "stdout", - "stderr" - ], - "inputProperties": { - "interpreter": { - "description": "The program and arguments to run the command.\nOn Linux and macOS, defaults to: `[\"/bin/sh\", \"-c\"]`. On Windows, defaults to: `[\"cmd\", \"/C\"]`", - "type": "array", - "items": { - "type": "string" - } - }, - "dir": { - "description": "The working directory in which to run the command from.", - "type": "string" - }, - "environment": { - "description": "Additional environment variables available to the command's process.", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "triggers": { - "type": "array", - "items": { - "$ref": "pulumi.json#/Any" - } - }, - "create": { - "type": "string", - "description": "The command to run on create." - }, - "delete": { - "type": "string", - "description": "The command to run on delete." - } - }, - "requiredInputs": [] - }, - "command:remote:Command": { - "description": "A command to run on a remote host.\nThe connection is established via ssh.", - "properties": { - "connection": { - "description": "The parameters with which to connect to the remote host", - "$ref": "#/types/command:remote:Connection" - }, - "environment": { - "description": "Additional environment variables available to the command's process.", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "triggers": { - "description": "Trigger replacements on changes to this input.", - "type": "array", - "items": { - "$ref": "pulumi.json#/Any" - } - }, - "create": { - "description": "The command to run on create.", - "type": "string" - }, - "delete": { - "description": "The command to run on delete.", - "type": "string" - }, - "stdout": { - "description": "The standard output of the command's process", - "type": "string" - }, - "stderr": { - "description": "The standard error of the command's process", - "type": "string" - } - }, - "required": [ - "stdout", - "stderr" - ], - "inputProperties": { - "connection": { - "description": "The parameters with which to connect to the remote host.", - "$ref": "#/types/command:remote:Connection" - }, - "environment": { - "description": "Additional environment variables available to the command's process.", - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "triggers": { - "description": "Trigger replacements on changes to this input.", - "type": "array", - "items": { - "$ref": "pulumi.json#/Any" - } - }, - "create": { - "description": "The command to run on create.", - "type": "string" - }, - "delete": { - "description": "The command to run on delete.", - "type": "string" - } - }, - "requiredInputs": [ - "connection" - ] - }, - "command:remote:CopyFile": { - "description": "Copy a local file to a remote host.", - "inputProperties": { - "connection": { - "description": "The parameters with which to connect to the remote host.", - "$ref": "#/types/command:remote:Connection" - }, - "triggers": { - "description": "Trigger replacements on changes to this input.", - "type": "array", - "items": { - "$ref": "pulumi.json#/Any" - } - }, - "localPath": { - "description": "The path of the file to be copied.", - "type": "string" - }, - "remotePath": { - "description": "The destination path in the remote host.", - "type": "string" - } - }, - "requiredInputs": [ - "connection", - "localPath", - "remotePath" - ], - "properties": { - "connection": { - "description": "The parameters with which to connect to the remote host.", - "$ref": "#/types/command:remote:Connection" - }, - "triggers": { - "description": "Trigger replacements on changes to this input.", - "type": "array", - "items": { - "$ref": "pulumi.json#/Any" - } - }, - "localPath": { - "description": "The path of the file to be copied.", - "type": "string" - }, - "remotePath": { - "description": "The destination path in the remote host.", - "type": "string" - } - }, - "required": [ - "connection", - "localPath", - "remotePath" - ] - } - }, - "language": { - "csharp": { - "packageReferences": { - "Pulumi": "3.*" - } - }, - "go": { - "generateResourceContainerTypes": true, - "importBasePath": "github.com/pulumi/pulumi-command/sdk/go/command" - }, - "nodejs": { - "dependencies": { - "@pulumi/pulumi": "^3.0.0" - } - }, - "python": { - "requires": { - "pulumi": ">=3.0.0,<4.0.0" - } - } - } -} diff --git a/Pulumi.FSharp.Core/Assets.fs b/Pulumi.FSharp.Core/Assets.fs deleted file mode 100644 index 1817640..0000000 --- a/Pulumi.FSharp.Core/Assets.fs +++ /dev/null @@ -1,48 +0,0 @@ -module Pulumi.FSharp.Assets - -open System.Collections.Generic -open Pulumi - -type FileArchive = { - ArchivePath: string -} with member this.ToPulumiType = FileArchive(this.ArchivePath) - -type RemoteArchive = { - ArchiveUri: string -} with member this.ToPulumiType = RemoteArchive(this.ArchiveUri) - -type RemoteAsset = { - Uri: string -} with member this.ToPulumiType = RemoteAsset(this.Uri) - -type FileAsset = { - Path: string -} with member this.ToPulumiType = FileAsset(this.Path) - -type StringAsset = { - Text: string -} with member this.ToPulumiType = StringAsset(this.Text) - -type Any = { - Value: obj -} - -type Asset = - | File of FileAsset - | FileArchive of FileArchive - | Remote of RemoteAsset - | RemoteArchive of RemoteArchive - | String of StringAsset - -type AssetArchive = { - Assets: Map -} with member this.ToPulumiType = - this.Assets |> - Map.map (fun _ a -> match a with - | File f -> f.ToPulumiType :> AssetOrArchive - | FileArchive f -> f.ToPulumiType :> AssetOrArchive - | Remote f -> f.ToPulumiType :> AssetOrArchive - | RemoteArchive f -> f.ToPulumiType :> AssetOrArchive - | String f -> f.ToPulumiType :> AssetOrArchive) |> - Dictionary |> - AssetArchive \ No newline at end of file diff --git a/Pulumi.FSharp.Core/Config.fs b/Pulumi.FSharp.Core/Config.fs deleted file mode 100644 index d1f6f96..0000000 --- a/Pulumi.FSharp.Core/Config.fs +++ /dev/null @@ -1,17 +0,0 @@ -module Pulumi.FSharp.Config - -open Pulumi - -let private pulumiConfig = Lazy(fun _ -> Config()) - -type Config() = - member _.Item - with get(name) = pulumiConfig.Value.Require(name) - -type SecretConfig() = - member _.Item - with get(name) = pulumiConfig.Value.RequireSecret(name) - -// Type provider for YAML config variables -let config = Config() -let secret = SecretConfig() \ No newline at end of file diff --git a/Pulumi.FSharp.Core/OutputBuilder.fs b/Pulumi.FSharp.Core/OutputBuilder.fs deleted file mode 100644 index 0940cb0..0000000 --- a/Pulumi.FSharp.Core/OutputBuilder.fs +++ /dev/null @@ -1,27 +0,0 @@ -module Pulumi.FSharp.Outputs - -open Pulumi -open System.Threading.Tasks - -type OutputBuilder internal (isSecret) = - let create (value : 'a) = - match isSecret with - | true -> Output.CreateSecret<'a>(value) - | false -> Output.Create<'a>(value) - - member __.Return (x : 'a) = - create x - - member __.Bind (comp : Output<'a>, func : 'a -> Output<'b>) = - comp.Apply<'b>(func) - - member this.Bind (comp : Task<'a>, func : 'a -> Output<'b>) = - this.Bind((match isSecret with - | false -> Output.Create<'a>(comp) - | true -> Output.CreateSecret<'a>(comp)), func) - - member __.ReturnFrom (v : Output<_>) = - v - -let output = OutputBuilder(isSecret = false) -let secretOutput = OutputBuilder(isSecret = true) \ No newline at end of file diff --git a/Pulumi.FSharp.Core/Pulumi.FSharp.Core.fsproj b/Pulumi.FSharp.Core/Pulumi.FSharp.Core.fsproj deleted file mode 100644 index b4bd6b6..0000000 --- a/Pulumi.FSharp.Core/Pulumi.FSharp.Core.fsproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2020 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi azure - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - 3.1.5 - NU1605,NU1608 - true - 6.0.* - - - - - - - - - - - - - - - - - - diff --git a/Pulumi.FSharp.Core/build.fsx b/Pulumi.FSharp.Core/build.fsx deleted file mode 100644 index 165c8e2..0000000 --- a/Pulumi.FSharp.Core/build.fsx +++ /dev/null @@ -1,98 +0,0 @@ -#r "paket: -nuget FSharp.Core 4.7.2 -nuget Fake.DotNet.Cli -nuget Fake.IO.FileSystem -nuget Fake.BuildServer.TeamFoundation -nuget Fake.Core.CommandLineParsing -nuget Fake.Core.Xml -nuget Fake.Core.Target //" -#load ".fake/build.fsx/intellisense.fsx" -#nowarn "52" -open Fake.IO.Globbing.Operators -open Fake.Core.TargetOperators -open Fake.BuildServer -open Fake.DotNet -open Fake.Core -open System.IO - -BuildServer.install [ TeamFoundation.Installer ] - -let args = - Context.forceFakeContext().Arguments |> - Array.ofList |> - Docopt(""" -usage: dotnet_fake_run_build.fsx [options] - -options: - -t - """).Parse - -let getTarget args = - match Map.tryFind "-t" args with - | Some (Argument t) -> t - | _ -> "Default" - -let getProjectFile () = - !! "**/Pulumi.FSharp.Core.fsproj" |> Seq.head - -Target.create "Install" (fun _ -> - DotNet.Options.Create() |> - DotNet.install DotNet.Versions.FromGlobalJson |> - ignore -) - -Target.create "Build" (fun _ -> - let buildOptions options : DotNet.BuildOptions = { - options with - Common = { - options.Common with - Verbosity = Some DotNet.Verbosity.Quiet - } - NoLogo = true - } - - getProjectFile () |> - DotNet.build buildOptions -) - -Target.create "Pack" (fun _ -> - getProjectFile () |> - DotNet.pack (fun po -> { po with MSBuildParams = { po.MSBuildParams with DisableInternalBinLog = true } }) -) - -Target.create "Push" (fun _ -> - let vaultFile = - Environment.environVarOrNone "FAKEVAULTFILE_SECUREFILEPATH" |> - Option.defaultValue "Pulumi.FSharp.Extensions.vault.json" |> - FileInfo - - let vault = - match Vault.fromFakeEnvironmentOrNone(), vaultFile.Exists with - | Some vault, _ -> vault - | None , true -> vaultFile.OpenText().ReadToEnd() |> Vault.fromJson - | None , false -> failwith "Unsupported source for secrets" - - let pushOptions options : DotNet.NuGetPushOptions = { - options with - PushParams = { - options.PushParams with - ApiKey = Vault.tryGet "nuGetApiKey" vault - Source = Some "https://api.nuget.org/v3/index.json" - } - } - - !! "**/Pulumi.FSharp.Core.*.nupkg" |> - Seq.exactlyOne |> - DotNet.nugetPush pushOptions -) - -Target.create "Default" ignore - -"Install" ==> -"Pack" =?> -("Push" , not BuildServer.isLocalBuild) ==> -"Default" - -args |> -getTarget |> -Target.runOrDefaultWithArguments \ No newline at end of file diff --git a/Pulumi.FSharp.Docker/Myriad.fs b/Pulumi.FSharp.Docker/Myriad.fs deleted file mode 100644 index 254b796..0000000 --- a/Pulumi.FSharp.Docker/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private Docker - -module Force = let private nonce = 780245980 \ No newline at end of file diff --git a/Pulumi.FSharp.Docker/Pulumi.FSharp.Docker.fsproj b/Pulumi.FSharp.Docker/Pulumi.FSharp.Docker.fsproj deleted file mode 100644 index d66d794..0000000 --- a/Pulumi.FSharp.Docker/Pulumi.FSharp.Docker.fsproj +++ /dev/null @@ -1,59 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2021 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi docker - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - - - diff --git a/Pulumi.FSharp.Extensions.sln b/Pulumi.FSharp.Extensions.sln index b903f42..f949c32 100644 --- a/Pulumi.FSharp.Extensions.sln +++ b/Pulumi.FSharp.Extensions.sln @@ -1,118 +1,133 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Myriad", "Pulumi.FSharp.Myriad\Pulumi.FSharp.Myriad.fsproj", "{EDDFE9E5-9B82-4ECF-AB23-86F3347D77EC}" +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{28C09E13-D45B-40D2-AAB0-F7D3A69417D8}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Azure", "Pulumi.FSharp.Azure\Pulumi.FSharp.Azure.fsproj", "{0CDB4B8E-343B-45A5-A1C6-951470C965F9}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Core", "src\Pulumi.FSharp.Core\Pulumi.FSharp.Core.fsproj", "{7A74E40C-7A88-4683-807B-26FE69C00C9E}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Core", "Pulumi.FSharp.Core\Pulumi.FSharp.Core.fsproj", "{163493B5-0F35-4298-AB85-C9B3D92D570A}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Myriad", "src\Pulumi.FSharp.Myriad\Pulumi.FSharp.Myriad.fsproj", "{39E6A928-3D66-4D1D-9F12-5CAE5C47D82B}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Test", "Pulumi.FSharp.Test\Pulumi.FSharp.Test.fsproj", "{E68C417A-34D7-4953-B0D5-B43FD833A0C8}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "providers", "providers", "{6A29027D-A6AF-406A-B0E5-FBBBD9962BFC}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.NuGet.Test", "Pulumi.FSharp.NuGet.Test\Pulumi.FSharp.NuGet.Test.fsproj", "{290AD0BD-D3B5-4B90-860F-0E14407BFD46}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Auth0", "providers\Pulumi.FSharp.Auth0\Pulumi.FSharp.Auth0.fsproj", "{23F69D6B-8674-49A3-A872-70F06F8A982C}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Aws", "Pulumi.FSharp.Aws\Pulumi.FSharp.Aws.fsproj", "{570555D8-4272-47CD-96F7-40817A67B41E}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Aws", "providers\Pulumi.FSharp.Aws\Pulumi.FSharp.Aws.fsproj", "{6EA504F0-BCD6-4A6A-9897-651BFC4B06E3}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Kubernetes", "Pulumi.FSharp.Kubernetes\Pulumi.FSharp.Kubernetes.fsproj", "{8E9160DC-5EE5-4D66-AE13-66183C04A6C3}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Azure", "providers\Pulumi.FSharp.Azure\Pulumi.FSharp.Azure.fsproj", "{8AAE2E3E-CCE6-440F-83B2-085394C65760}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{DA33B8DE-E8FB-49FB-B79A-D156179C56CA}" - ProjectSection(SolutionItems) = preProject - README.md = README.md - EndProjectSection +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.AzureAD", "providers\Pulumi.FSharp.AzureAD\Pulumi.FSharp.AzureAD.fsproj", "{144FE576-0844-42EB-956F-812AF5EC9AE1}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.AzureAD", "Pulumi.FSharp.AzureAD\Pulumi.FSharp.AzureAD.fsproj", "{D743DF85-53C4-4E5B-B7E0-8A3AE58B7B3A}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.AzureNative", "providers\Pulumi.FSharp.AzureNative\Pulumi.FSharp.AzureNative.fsproj", "{787A81CE-6A67-4882-AB27-D29932659EE4}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Pipelines", "Pipelines", "{19133DA2-F039-47AB-A225-6435EC14A67B}" - ProjectSection(SolutionItems) = preProject - build.fsx = build.fsx - FAKE.yml = FAKE.yml - EndProjectSection +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.AzureNativeV2", "providers\Pulumi.FSharp.AzureNativeV2\Pulumi.FSharp.AzureNativeV2.fsproj", "{0DC17401-17FD-454D-8074-3CDDBB092C0C}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.AzureNative", "Pulumi.FSharp.AzureNative\Pulumi.FSharp.AzureNative.fsproj", "{82654FE1-17B2-45B0-A967-19546970D378}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Command", "providers\Pulumi.FSharp.Command\Pulumi.FSharp.Command.fsproj", "{29DE140F-E25F-4B7F-B531-04D461EAE9F1}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Gcp", "Pulumi.FSharp.Gcp\Pulumi.FSharp.Gcp.fsproj", "{FB88475F-F6DE-4E2D-965B-8E06514F89E3}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.DigitalOcean", "providers\Pulumi.FSharp.DigitalOcean\Pulumi.FSharp.DigitalOcean.fsproj", "{07F2BD4B-55DD-4460-8068-D397A40363B2}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Tls", "Pulumi.FSharp.Tls\Pulumi.FSharp.Tls.fsproj", "{C7ACAED9-A76D-4C83-A5CF-6583B5705F95}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Docker", "providers\Pulumi.FSharp.Docker\Pulumi.FSharp.Docker.fsproj", "{F982AD8D-18DA-48BA-8AB1-B62537D93EC9}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Random", "Pulumi.FSharp.Random\Pulumi.FSharp.Random.fsproj", "{D3ABE35A-70D4-4D9E-882B-21E706D871E1}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Gcp", "providers\Pulumi.FSharp.Gcp\Pulumi.FSharp.Gcp.fsproj", "{170F0B9B-106A-4F3F-8CA9-1533990D2FF4}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Command", "Pulumi.FSharp.Command\Pulumi.FSharp.Command.fsproj", "{5EB201F8-FC48-4F8B-B50D-780FA6FADDD8}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Kubernetes", "providers\Pulumi.FSharp.Kubernetes\Pulumi.FSharp.Kubernetes.fsproj", "{821526F5-26CA-4E8D-A4C6-7D77F317AAB3}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Docker", "Pulumi.FSharp.Docker\Pulumi.FSharp.Docker.fsproj", "{428CED50-DFBF-48EF-B9B3-FB3B4CC4E0FB}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Random", "providers\Pulumi.FSharp.Random\Pulumi.FSharp.Random.fsproj", "{DF4FE3E4-1EA2-4A82-96EA-7CD0036B77F2}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.AzureNativeV2", "Pulumi.FSharp.AzureNativeV2\Pulumi.FSharp.AzureNativeV2.fsproj", "{C93C3853-4894-4CB6-9F1E-3CD544E10870}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.Tls", "providers\Pulumi.FSharp.Tls\Pulumi.FSharp.Tls.fsproj", "{6CE90EBD-D118-4707-BB8C-B3E96F2A7992}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Pulumi.FSharp.AzureNative.Common", "Pulumi.FSharp.AzureNative.Common\Pulumi.FSharp.AzureNative.Common.fsproj", "{A01D65E8-98E4-41A2-BA49-67CC4CB9126A}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "build", "build\build.fsproj", "{F001F2EE-9ED0-4FE0-87F6-0365F1CA887E}" 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 - {EDDFE9E5-9B82-4ECF-AB23-86F3347D77EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EDDFE9E5-9B82-4ECF-AB23-86F3347D77EC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EDDFE9E5-9B82-4ECF-AB23-86F3347D77EC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EDDFE9E5-9B82-4ECF-AB23-86F3347D77EC}.Release|Any CPU.Build.0 = Release|Any CPU - {0CDB4B8E-343B-45A5-A1C6-951470C965F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0CDB4B8E-343B-45A5-A1C6-951470C965F9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0CDB4B8E-343B-45A5-A1C6-951470C965F9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0CDB4B8E-343B-45A5-A1C6-951470C965F9}.Release|Any CPU.Build.0 = Release|Any CPU - {163493B5-0F35-4298-AB85-C9B3D92D570A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {163493B5-0F35-4298-AB85-C9B3D92D570A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {163493B5-0F35-4298-AB85-C9B3D92D570A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {163493B5-0F35-4298-AB85-C9B3D92D570A}.Release|Any CPU.Build.0 = Release|Any CPU - {E68C417A-34D7-4953-B0D5-B43FD833A0C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E68C417A-34D7-4953-B0D5-B43FD833A0C8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E68C417A-34D7-4953-B0D5-B43FD833A0C8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E68C417A-34D7-4953-B0D5-B43FD833A0C8}.Release|Any CPU.Build.0 = Release|Any CPU - {290AD0BD-D3B5-4B90-860F-0E14407BFD46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {290AD0BD-D3B5-4B90-860F-0E14407BFD46}.Debug|Any CPU.Build.0 = Debug|Any CPU - {290AD0BD-D3B5-4B90-860F-0E14407BFD46}.Release|Any CPU.ActiveCfg = Release|Any CPU - {290AD0BD-D3B5-4B90-860F-0E14407BFD46}.Release|Any CPU.Build.0 = Release|Any CPU - {570555D8-4272-47CD-96F7-40817A67B41E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {570555D8-4272-47CD-96F7-40817A67B41E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {570555D8-4272-47CD-96F7-40817A67B41E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {570555D8-4272-47CD-96F7-40817A67B41E}.Release|Any CPU.Build.0 = Release|Any CPU - {8E9160DC-5EE5-4D66-AE13-66183C04A6C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8E9160DC-5EE5-4D66-AE13-66183C04A6C3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8E9160DC-5EE5-4D66-AE13-66183C04A6C3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8E9160DC-5EE5-4D66-AE13-66183C04A6C3}.Release|Any CPU.Build.0 = Release|Any CPU - {D743DF85-53C4-4E5B-B7E0-8A3AE58B7B3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D743DF85-53C4-4E5B-B7E0-8A3AE58B7B3A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D743DF85-53C4-4E5B-B7E0-8A3AE58B7B3A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D743DF85-53C4-4E5B-B7E0-8A3AE58B7B3A}.Release|Any CPU.Build.0 = Release|Any CPU - {82654FE1-17B2-45B0-A967-19546970D378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {82654FE1-17B2-45B0-A967-19546970D378}.Debug|Any CPU.Build.0 = Debug|Any CPU - {82654FE1-17B2-45B0-A967-19546970D378}.Release|Any CPU.ActiveCfg = Release|Any CPU - {82654FE1-17B2-45B0-A967-19546970D378}.Release|Any CPU.Build.0 = Release|Any CPU - {FB88475F-F6DE-4E2D-965B-8E06514F89E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FB88475F-F6DE-4E2D-965B-8E06514F89E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FB88475F-F6DE-4E2D-965B-8E06514F89E3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FB88475F-F6DE-4E2D-965B-8E06514F89E3}.Release|Any CPU.Build.0 = Release|Any CPU - {C7ACAED9-A76D-4C83-A5CF-6583B5705F95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C7ACAED9-A76D-4C83-A5CF-6583B5705F95}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C7ACAED9-A76D-4C83-A5CF-6583B5705F95}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C7ACAED9-A76D-4C83-A5CF-6583B5705F95}.Release|Any CPU.Build.0 = Release|Any CPU - {D3ABE35A-70D4-4D9E-882B-21E706D871E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D3ABE35A-70D4-4D9E-882B-21E706D871E1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D3ABE35A-70D4-4D9E-882B-21E706D871E1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D3ABE35A-70D4-4D9E-882B-21E706D871E1}.Release|Any CPU.Build.0 = Release|Any CPU - {5EB201F8-FC48-4F8B-B50D-780FA6FADDD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5EB201F8-FC48-4F8B-B50D-780FA6FADDD8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5EB201F8-FC48-4F8B-B50D-780FA6FADDD8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5EB201F8-FC48-4F8B-B50D-780FA6FADDD8}.Release|Any CPU.Build.0 = Release|Any CPU - {428CED50-DFBF-48EF-B9B3-FB3B4CC4E0FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {428CED50-DFBF-48EF-B9B3-FB3B4CC4E0FB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {428CED50-DFBF-48EF-B9B3-FB3B4CC4E0FB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {428CED50-DFBF-48EF-B9B3-FB3B4CC4E0FB}.Release|Any CPU.Build.0 = Release|Any CPU - {C93C3853-4894-4CB6-9F1E-3CD544E10870}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C93C3853-4894-4CB6-9F1E-3CD544E10870}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C93C3853-4894-4CB6-9F1E-3CD544E10870}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C93C3853-4894-4CB6-9F1E-3CD544E10870}.Release|Any CPU.Build.0 = Release|Any CPU - {A01D65E8-98E4-41A2-BA49-67CC4CB9126A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A01D65E8-98E4-41A2-BA49-67CC4CB9126A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A01D65E8-98E4-41A2-BA49-67CC4CB9126A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A01D65E8-98E4-41A2-BA49-67CC4CB9126A}.Release|Any CPU.Build.0 = Release|Any CPU + {7A74E40C-7A88-4683-807B-26FE69C00C9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7A74E40C-7A88-4683-807B-26FE69C00C9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7A74E40C-7A88-4683-807B-26FE69C00C9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7A74E40C-7A88-4683-807B-26FE69C00C9E}.Release|Any CPU.Build.0 = Release|Any CPU + {39E6A928-3D66-4D1D-9F12-5CAE5C47D82B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {39E6A928-3D66-4D1D-9F12-5CAE5C47D82B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {39E6A928-3D66-4D1D-9F12-5CAE5C47D82B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {39E6A928-3D66-4D1D-9F12-5CAE5C47D82B}.Release|Any CPU.Build.0 = Release|Any CPU + {23F69D6B-8674-49A3-A872-70F06F8A982C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23F69D6B-8674-49A3-A872-70F06F8A982C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23F69D6B-8674-49A3-A872-70F06F8A982C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23F69D6B-8674-49A3-A872-70F06F8A982C}.Release|Any CPU.Build.0 = Release|Any CPU + {6EA504F0-BCD6-4A6A-9897-651BFC4B06E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6EA504F0-BCD6-4A6A-9897-651BFC4B06E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6EA504F0-BCD6-4A6A-9897-651BFC4B06E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6EA504F0-BCD6-4A6A-9897-651BFC4B06E3}.Release|Any CPU.Build.0 = Release|Any CPU + {8AAE2E3E-CCE6-440F-83B2-085394C65760}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8AAE2E3E-CCE6-440F-83B2-085394C65760}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8AAE2E3E-CCE6-440F-83B2-085394C65760}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8AAE2E3E-CCE6-440F-83B2-085394C65760}.Release|Any CPU.Build.0 = Release|Any CPU + {144FE576-0844-42EB-956F-812AF5EC9AE1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {144FE576-0844-42EB-956F-812AF5EC9AE1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {144FE576-0844-42EB-956F-812AF5EC9AE1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {144FE576-0844-42EB-956F-812AF5EC9AE1}.Release|Any CPU.Build.0 = Release|Any CPU + {787A81CE-6A67-4882-AB27-D29932659EE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {787A81CE-6A67-4882-AB27-D29932659EE4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {787A81CE-6A67-4882-AB27-D29932659EE4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {787A81CE-6A67-4882-AB27-D29932659EE4}.Release|Any CPU.Build.0 = Release|Any CPU + {0DC17401-17FD-454D-8074-3CDDBB092C0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0DC17401-17FD-454D-8074-3CDDBB092C0C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0DC17401-17FD-454D-8074-3CDDBB092C0C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0DC17401-17FD-454D-8074-3CDDBB092C0C}.Release|Any CPU.Build.0 = Release|Any CPU + {29DE140F-E25F-4B7F-B531-04D461EAE9F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29DE140F-E25F-4B7F-B531-04D461EAE9F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29DE140F-E25F-4B7F-B531-04D461EAE9F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29DE140F-E25F-4B7F-B531-04D461EAE9F1}.Release|Any CPU.Build.0 = Release|Any CPU + {07F2BD4B-55DD-4460-8068-D397A40363B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07F2BD4B-55DD-4460-8068-D397A40363B2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07F2BD4B-55DD-4460-8068-D397A40363B2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07F2BD4B-55DD-4460-8068-D397A40363B2}.Release|Any CPU.Build.0 = Release|Any CPU + {F982AD8D-18DA-48BA-8AB1-B62537D93EC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F982AD8D-18DA-48BA-8AB1-B62537D93EC9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F982AD8D-18DA-48BA-8AB1-B62537D93EC9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F982AD8D-18DA-48BA-8AB1-B62537D93EC9}.Release|Any CPU.Build.0 = Release|Any CPU + {170F0B9B-106A-4F3F-8CA9-1533990D2FF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {170F0B9B-106A-4F3F-8CA9-1533990D2FF4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {170F0B9B-106A-4F3F-8CA9-1533990D2FF4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {170F0B9B-106A-4F3F-8CA9-1533990D2FF4}.Release|Any CPU.Build.0 = Release|Any CPU + {821526F5-26CA-4E8D-A4C6-7D77F317AAB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {821526F5-26CA-4E8D-A4C6-7D77F317AAB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {821526F5-26CA-4E8D-A4C6-7D77F317AAB3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {821526F5-26CA-4E8D-A4C6-7D77F317AAB3}.Release|Any CPU.Build.0 = Release|Any CPU + {DF4FE3E4-1EA2-4A82-96EA-7CD0036B77F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DF4FE3E4-1EA2-4A82-96EA-7CD0036B77F2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DF4FE3E4-1EA2-4A82-96EA-7CD0036B77F2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DF4FE3E4-1EA2-4A82-96EA-7CD0036B77F2}.Release|Any CPU.Build.0 = Release|Any CPU + {6CE90EBD-D118-4707-BB8C-B3E96F2A7992}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CE90EBD-D118-4707-BB8C-B3E96F2A7992}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CE90EBD-D118-4707-BB8C-B3E96F2A7992}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CE90EBD-D118-4707-BB8C-B3E96F2A7992}.Release|Any CPU.Build.0 = Release|Any CPU + {F001F2EE-9ED0-4FE0-87F6-0365F1CA887E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F001F2EE-9ED0-4FE0-87F6-0365F1CA887E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F001F2EE-9ED0-4FE0-87F6-0365F1CA887E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F001F2EE-9ED0-4FE0-87F6-0365F1CA887E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {7A74E40C-7A88-4683-807B-26FE69C00C9E} = {28C09E13-D45B-40D2-AAB0-F7D3A69417D8} + {39E6A928-3D66-4D1D-9F12-5CAE5C47D82B} = {28C09E13-D45B-40D2-AAB0-F7D3A69417D8} + {23F69D6B-8674-49A3-A872-70F06F8A982C} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {6EA504F0-BCD6-4A6A-9897-651BFC4B06E3} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {8AAE2E3E-CCE6-440F-83B2-085394C65760} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {144FE576-0844-42EB-956F-812AF5EC9AE1} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {787A81CE-6A67-4882-AB27-D29932659EE4} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {0DC17401-17FD-454D-8074-3CDDBB092C0C} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {29DE140F-E25F-4B7F-B531-04D461EAE9F1} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {07F2BD4B-55DD-4460-8068-D397A40363B2} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {F982AD8D-18DA-48BA-8AB1-B62537D93EC9} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {170F0B9B-106A-4F3F-8CA9-1533990D2FF4} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {821526F5-26CA-4E8D-A4C6-7D77F317AAB3} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {DF4FE3E4-1EA2-4A82-96EA-7CD0036B77F2} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} + {6CE90EBD-D118-4707-BB8C-B3E96F2A7992} = {6A29027D-A6AF-406A-B0E5-FBBBD9962BFC} EndGlobalSection EndGlobal diff --git a/Pulumi.FSharp.Gcp/Myriad.fs b/Pulumi.FSharp.Gcp/Myriad.fs deleted file mode 100644 index 73ea4e4..0000000 --- a/Pulumi.FSharp.Gcp/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private Gcp - -module Force = let private nonce = 2005552723 \ No newline at end of file diff --git a/Pulumi.FSharp.Gcp/Pulumi.FSharp.Gcp.fsproj b/Pulumi.FSharp.Gcp/Pulumi.FSharp.Gcp.fsproj deleted file mode 100644 index 824e9f3..0000000 --- a/Pulumi.FSharp.Gcp/Pulumi.FSharp.Gcp.fsproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2021 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi gcp - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - diff --git a/Pulumi.FSharp.Kubernetes/Myriad.fs b/Pulumi.FSharp.Kubernetes/Myriad.fs deleted file mode 100644 index 0de574b..0000000 --- a/Pulumi.FSharp.Kubernetes/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private Kubernetes - -//module Force = let private nonce = 22515 \ No newline at end of file diff --git a/Pulumi.FSharp.Kubernetes/Pulumi.FSharp.Kubernetes.fsproj b/Pulumi.FSharp.Kubernetes/Pulumi.FSharp.Kubernetes.fsproj deleted file mode 100644 index 22c1b6a..0000000 --- a/Pulumi.FSharp.Kubernetes/Pulumi.FSharp.Kubernetes.fsproj +++ /dev/null @@ -1,58 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2020 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi kubernetes - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - - diff --git a/Pulumi.FSharp.Myriad/AstHelpers.fs b/Pulumi.FSharp.Myriad/AstHelpers.fs deleted file mode 100644 index ab440ef..0000000 --- a/Pulumi.FSharp.Myriad/AstHelpers.fs +++ /dev/null @@ -1,298 +0,0 @@ -module AstHelpers - -open FSharp.Compiler.Syntax -open FSharp.Compiler.SyntaxTrivia -open FSharp.Compiler.Text -open Core -open Myriad.Core.Ast -open Myriad.Core.AstExtensions - -type SimplePat = - /// str - static member id(str) = - SynSimplePat.Id(Ident.Create(str), None, false, false, false, range.Zero) - - static member typed(str, type' : string) = - SynSimplePat.Typed(SimplePat.id(str), - SynType.CreateLongIdent(type'), - range.Zero) - -type SynPat with - static member CreateTuple(args : SynPat list) = - SynPat.Tuple(false, args, Range.Zero) - -type Pat = - static member tuple(left, right) = - SynPat.CreateTuple([ - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(left), []) - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(right), []) - ]) - - static member tuple(one, two, three) = - SynPat.CreateTuple([ - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(one), []) - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(two), []) - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(three), []) - ]) - - static member tuple(one, two, three, four) = - SynPat.CreateTuple([ - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(one), []) - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(two), []) - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(three), []) - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(four), []) - ]) - - static member tuple(left : SynPat, right : SynPat) = - SynPat.CreateTuple([ - left - right - ]) - - static member paren(pat : SynPat) = - SynPat.CreateParen(pat) - - static member ident(str) = - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(str), []) - - static member null' = - SynPat.Null(range.Zero) - - static member wild = - SynPat.Wild(range.Zero) - - static member typed(name, typeName : string) = - SynPat.Typed(Pat.ident(name), SynType.CreateLongIdent(typeName), range.Zero) |> - SynPat.CreateParen - -type Expr = - /// str - static member ident(str) = - SynExpr.CreateIdent(Ident.Create(str)) - - /// str.str - static member longIdent(str) = - SynExpr.CreateLongIdent(LongIdentWithDots.CreateString(str)) - - /// (exp) - static member paren(exp) = - SynExpr.CreateParen(exp) - - /// () - static member unit = - SynExpr.CreateUnit - - /// null - static member null' = - SynExpr.CreateNull - - /// (left, right) - static member tuple(left, right) = - SynExpr.CreateTuple([ - left - right - ]) - - /// (left, right) - static member tuple(one, two, three) = - SynExpr.CreateTuple([ - one - two - three - ]) - - static member tuple(one, two, three, four) = - SynExpr.CreateTuple([ - one - two - three - four - ]) - - /// (a, b, c, ...) - static member tuple(exps) = - SynExpr.CreateTuple(exps) - - /// [ ... ] - static member list(exps) = - SynExpr.ArrayOrList( - false, - exps, - range.Zero - ) - - /// [ ... ] - static member list(idents) = - SynExpr.ArrayOrList( - false, - idents |> List.map Expr.ident, - range.Zero - ) - - /// exp1 - /// exp2 - /// ... - static member sequential(exps) = - SynExpr.CreateSequential(exps) - - /// func arg - static member app(func, arg) = - SynExpr.CreateApp(func, arg) - - /// func arg1 arg2 ... - static member app(func : SynExpr, args : SynExpr list) = - match args with - | [ ] -> Expr.app(func, Expr.unit) - | [x] -> Expr.app(func, x) - | x :: xs -> Expr.app(Expr.app(func, x), xs) - - /// func arg1 arg2 ... - static member app(func : string, args : SynExpr list) = - Expr.app((Expr.longIdent(func) : SynExpr), args) - - /// func arg - static member app(func : string, arg : string) = - Expr.app(Expr.longIdent(func), Expr.ident(arg)) - - /// func arg - static member app(func : string, arg : SynExpr) = - Expr.app(Expr.longIdent(func), arg) - - /// func (arg1, arg2, ...) - static member appTuple(func : string, args) = - Expr.app(func, - Expr.paren(Expr.tuple(args |> List.map Expr.ident))) - - static member match'(expr, clauses) = - SynExpr.CreateMatch(expr, clauses) - - /// value - static member const'(value) = - SynExpr.CreateConstString(value) - - /// failwith msg - static member failwith(msg) = - Expr.app("failwith", Expr.const'(msg)) - - static member let'(name, args : SynPat list, exp) = - SynExpr.LetOrUse( - false, - false, - [ - SynBinding.Let( - pattern = SynPat.CreateLongIdent(LongIdentWithDots.CreateString(name), args), - expr = exp) - ], - Expr.unit, - range.Zero, - { InKeyword = None }) - - static member let'(name, args, exp) = - SynExpr.LetOrUse( - false, - false, - [ - SynBinding.Let( - pattern = SynPat.CreateLongIdent(LongIdentWithDots.CreateString(name), - (args |> List.map Pat.ident)), - expr = exp) - ], - Expr.unit, - range.Zero, - { InKeyword = None }) - - static member set(identString, exp) = - SynExpr.Set (Expr.longIdent(identString), - exp, - range.Zero) - - static member methodCall(identString, exps) = - SynExpr.CreateInstanceMethodCall(LongIdentWithDots.CreateString(identString), - Expr.paren(Expr.tuple(exps))) - - static member lambda(args : SynSimplePat list, exp : SynExpr) = - let mapArgs = - function - | SynSimplePat.Id(x, _, _, _, _, _) -> - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(x.idText), []) - | SynSimplePat.Typed(SynSimplePat.Id(ident, _, _, _, _, _), targetType, _) -> - SynPat.CreateParen(SynPat.CreateTyped(SynPat.CreateLongIdent(LongIdentWithDots.CreateString(ident.idText), []), targetType)) - | x -> sprintf "%A" x |> failwith - - let pats = - args |> - List.map mapArgs - - let pat = - match pats with - | [] -> SynPat.CreateTuple(pats) - | [_] -> SynPat.CreateTuple(pats) - | _ -> SynPat.CreateParen(SynPat.CreateTuple(pats)) - - SynExpr.CreateLambda([pat], exp) - - static member lambda(args : string list, exp) = - SynExpr.CreateLambda(args |> List.map (fun x -> SynPat.CreateLongIdent(LongIdentWithDots.CreateString(x), [])), exp) - - //match args with - //| [ ] -> Expr.lambda(List.empty, exp) - //| [x] -> Expr.lambda([ SimplePat.id(x) ], exp) - //| x :: xs -> Expr.lambda([ SimplePat.id(x) ], Expr.lambda(xs, exp)) - -type Match = - static member clause(pat, expr) = - SynMatchClause.SynMatchClause(pat, - None, - expr, - range.Zero, - DebugPointAtTarget.No, - { ArrowRange = Some range.Zero; BarRange = Some range.Zero }) - -type Namespace = - static member namespace'(name, content) = - SynModuleOrNamespace.CreateNamespace(Ident.CreateLong name, decls = content) - -type Attribute = - static member attribute(name) = - SynAttributeList.Create(SynAttribute.Create(name)) - -type Module = - static member module'(name, content, attributes) = - let componentInfo = - SynComponentInfo.Create([ Ident.Create name ], attributes = attributes) - - SynModuleDecl.NestedModule(componentInfo, - false, - content, - false, - Range.Zero, - { EqualsRange = Some Range.Zero - ModuleKeyword = Some Range.Zero }) - - static member module'(name, content) = - Module.module'(name, content, []) - - static member autoOpenModule(name, content) = - Module.module'(name, content, [ Attribute.attribute("AutoOpen") ]) - - static member open'(namespaceOrModule) = - SynOpenDeclTarget.ModuleOrNamespace(LongIdentWithDots.CreateString(namespaceOrModule).Lid, range.Zero) |> - SynModuleDecl.CreateOpen - - static member type'(name, content) = - let t = SynTypeDefn.SynTypeDefn(SynComponentInfo.Create(Ident.CreateLong(name)), - SynTypeDefnRepr.ObjectModel(SynTypeDefnKind.Unspecified, - [SynMemberDefn.CreateImplicitCtor()], - Range.Zero), - content, - None, - Range.Zero, - { SynTypeDefnTrivia.TypeKeyword = Some Range.Zero - EqualsRange = Some Range.Zero - WithKeyword = None }) - - SynModuleDecl.Types([ t ], Range.Zero) - -type Type = - static member ctor() = - SynMemberDefn.CreateImplicitCtor() \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Attribute.fs b/Pulumi.FSharp.Myriad/Attribute.fs deleted file mode 100644 index 8af7d89..0000000 --- a/Pulumi.FSharp.Myriad/Attribute.fs +++ /dev/null @@ -1,16 +0,0 @@ -module AstAttribute - -open FSharp.Compiler.Text -open FSharp.Compiler.Syntax -open Myriad.Core.AstExtensions - -let createAttribute name = - SynAttributeList.Create(SynAttribute.Create(name)) - -let createAttributeWithArg (name : string) (arg : string) = - let o : SynAttribute = { TypeName = LongIdentWithDots.CreateString(name) - ArgExpr = SynExpr.CreateParen(SynExpr.CreateConstString(arg)) - Target = None - AppliesToGetterAndSetter = false - Range = range.Zero } - SynAttributeList.Create(o) \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Builder.fs b/Pulumi.FSharp.Myriad/Builder.fs deleted file mode 100644 index 38ec1bc..0000000 --- a/Pulumi.FSharp.Myriad/Builder.fs +++ /dev/null @@ -1,207 +0,0 @@ -module AstBuilder - -open AstOperations -open AstInstance -open AstHelpers -open AstMember -open AstYield -open AstRun -open Core - -open System.Text.RegularExpressions -open FSharp.Text.RegexProvider - -// "azure:compute/virtualMachine:VirtualMachine" -// CloudProvider - Always the same for each schema (azure here) -type InfoProvider = - Regex<"(?[a-z0-9-]+):(?[A-Za-z0-9.]+)(/(?\w+))?:(?\w+)"> - -let typeInfoProvider = - InfoProvider(RegexOptions.Compiled) - -type BuilderType = - | Type of InfoProvider.MatchType - | Resource of InfoProvider.MatchType - -let private argIdent = - Pat.ident("arg") - -let private argToInput = - Expr.app("input", "arg") - -let private args = - Expr.ident("args") - -let private funcIdent = - Expr.ident("func") - -let private yieldReturnExpr = - Expr.list([ Expr.ident("id") ]) - -let private combineExpr = - Expr.app("_combine", "args") - -let private combineCrosExpr = - Expr.app("_combineCros", "args") - -let private combineArgs = - Pat.ident("args") - -let private combineMember = - createMember' None "this" "Combine" combineArgs [] combineExpr - -let private combineCrosMember = - createMember' None "this" "Combine" combineArgs [] combineCrosExpr - -let private forArgs = - Pat.paren (Pat.tuple ("args", "delayedArgs")) - -let private forExpr = - Expr.methodCall("this.Combine", - [ Expr.ident("args") - Expr.app("delayedArgs", Expr.unit) ]) - -let private forMember = - createMember' None "this" "For" forArgs [] forExpr - -let private delayMember = - createMember "Delay" (Pat.ident("f")) [] (Expr.app("f", [])) - -let private zeroMember = - createMember "Zero" Pat.wild [] Expr.unit - -let private yieldMember isType = - createYield isType yieldReturnExpr yieldReturnExpr Expr.null' - -let private newNameExpr = - Expr.tuple(Expr.ident("newName"), - Expr.ident("args"), - Expr.ident("cros"), - Expr.ident("croI")) - -let private nameMember = - createNameOperation newNameExpr - -let createYieldFor argsType propType = - let setExpr = - Expr.sequential([ - Expr.set("args." + propType.Name, argToInput) - args - ]) - - let expr = - Expr.list([ - Expr.paren( - Expr.sequential([ - Expr.let'("func", [Pat.typed("args", argsType)], setExpr) - funcIdent - ]) - ) - ]) - - let cros = - Expr.list([Expr.ident("id")]) - let croI = Expr.null' - - [ createYield' (not propType.IsResource) argIdent expr cros croI ] - -let mapOperationType yieldSelector opsSelector = - function - | { Type = PRef _; CanGenerateYield = true } & pt -> yieldSelector pt - | { Type = PRef _ } & pt - | { Type = PString } & pt - | { Type = PInteger } & pt - | { Type = PFloat } & pt - | { Type = PBoolean } & pt - | { Type = PArray _ } & pt - | { Type = PUnion _ } & pt - | { Type = PJson _ } & pt - | { Type = PMap _ } & pt - | { Type = PAssetOrArchive _ } & pt - | { Type = PAny _ } & pt - | { Type = PArchive _ } & pt -> opsSelector pt - -let createBuilderClass isType name pTypes = - let argsType = - name + "Args" - - let croICheckNull () = - Expr.match' (Expr.ident "croI", - [Match.clause(Pat.null', createInstance "CustomResourceOptions" Expr.unit) - Match.clause(Pat.ident "croI", Expr.ident "croI")]) - - let apply varname = - Expr.app("List.fold", [ - Expr.paren(Expr.lambda([ varname; "f" ], Expr.app("f", varname))) - Expr.paren(match varname with | "args" -> createInstance argsType Expr.unit | _ -> croICheckNull()) - Expr.ident(varname) - ]) - - let resourceRunExp () = - Expr.paren( - Expr.tuple( - Expr.ident("name"), - (apply "args"), - (apply "cros") - )) |> - createInstance name - - let createOperations = - mapOperationType (createYieldFor argsType) - (createOperationsFor' argsType) - - let operations = - pTypes |> - Seq.collect createOperations - - let inputListOfInput argName = - Expr.app(Expr.ident("inputList"), - Expr.list([Expr.app(Expr.ident("input"), - Expr.ident(argName))])) - - let inputListOfResources argName = - Expr.app(Expr.ident("inputList"), - Expr.paren(Expr.app(Expr.longIdent("Seq.map"), - Expr.app(Expr.ident("input"), - Expr.ident(argName))))) - - Module.type'(name + "Builder", [ - //Type.ctor() - - yieldMember isType - - if isType then - apply "args" |> createRunType - else - resourceRunExp() |> createRunResource - - if isType then combineMember else combineCrosMember - forMember - delayMember - zeroMember - - yield! if isType then [] else [ nameMember ] - - yield! operations - - if not isType then - croOperation "DependsOn" - "Obsolete. Use customResourceOptions nested CE. Ensure this resource gets created after its dependency" - "dependency" - (inputListOfInput "dependency") - true - - if not isType then - croOperation "DependsOn" - "Obsolete. Use customResourceOptions nested CE. Ensure this resource gets created after its dependency" - "dependency" - (inputListOfResources "dependency") - false - - if not isType then - createYield' false - (Pat.typed("croI", "CustomResourceOptions")) - (Expr.list([Expr.ident("id")])) - (Expr.list([Expr.ident("id")])) - (Expr.ident("croI")) - ]) \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/BuilderInstance.fs b/Pulumi.FSharp.Myriad/BuilderInstance.fs deleted file mode 100644 index 8d476de..0000000 --- a/Pulumi.FSharp.Myriad/BuilderInstance.fs +++ /dev/null @@ -1,44 +0,0 @@ -module BuilderInstance - -open FSharp.Compiler.Syntax -open AstOperations -open AstInstance -open AstBuilder -open AstLet -open Myriad.Core.AstExtensions -open Core - -let createBuilderInstance description typeName pTypes = - let isYield, ops = - Array.partition (fun x -> x.CanGenerateYield && mapOperationType (fun _ -> true) (fun _ -> false) x) pTypes - - let builderNames = - isYield |> - Array.map (function - | { Type = PRef t } -> String.split ':' t |> Array.last |> toCamelCase - | x -> failwith $"{x} type should not use yield") - - let listItem = - sprintf " - %s" - - let title text = - $"*** {text} ***" - - let builderNamesSection = - match builderNames |> List.ofArray with - | [] -> [] - | bn -> "" :: title "Nested computational expressions" :: (List.map listItem bn) - - let descriptionShort = - description |> String.split '\n' |> Array.head - - let ccTypeName = - if typeName = "Input" then "input'" else typeName |> toCamelCase - - [ yield descriptionShort - yield "" - yield title "Operations" - yield! ops |> Array.map (fun x -> listItem x.OperationName) |> Array.collect (fun x -> [| ""; x |]) - yield! builderNamesSection |> List.collect (fun x -> [ ""; x ]) ] |> - createLet ccTypeName - (createInstance $"{typeName}Builder" SynExpr.CreateUnit) \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Core.fs b/Pulumi.FSharp.Myriad/Core.fs deleted file mode 100644 index eadec57..0000000 --- a/Pulumi.FSharp.Myriad/Core.fs +++ /dev/null @@ -1,32 +0,0 @@ -module Core - -open System -open FSharp.Compiler.Syntax -open Myriad.Core.Ast -open Myriad.Core.AstExtensions - -let private (|FirstLetter|) (p:string) = - p[0], p.Substring(1) - -let private changeInitial change value = - let (FirstLetter(x, xs)) = - value - - sprintf "%c%s" (change x) xs - -let toCamelCase = - changeInitial Char.ToLower - -let toPascalCase = - changeInitial Char.ToUpper - -let createPattern name args = - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(name), args) - -let (|Lazy|) (lazy' : Lazy<'a>) = - lazy'.Value - -module String = - let split (char : char) (value : string) = value.Split(char) - - let contains (subString : string) (value : string) = value.Contains(subString) \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Generator.fs b/Pulumi.FSharp.Myriad/Generator.fs deleted file mode 100644 index 4079892..0000000 --- a/Pulumi.FSharp.Myriad/Generator.fs +++ /dev/null @@ -1,59 +0,0 @@ -module Pulumi.FSharp.Myriad - -open AstNamespace -open IndexModule -open Myriad.Core -open AstModules -open System.Xml -open System.IO -open Schema - -[] -type PulumiFSharpGenerator() = - interface IMyriadGenerator with - member _.Generate(context) = - let projectFile = - FileInfo(context.InputFilename).Directory.EnumerateFiles("*.fsproj") |> - Seq.exactlyOne - - let provider = - projectFile.Name["Pulumi.FSharp.".Length..^".fsproj".Length] - - let providerNameOverride = - Map.empty - .Add("AzureNativeV2", "AzureNative") - - let provider = - providerNameOverride |> - Map.tryFind provider |> - Option.defaultValue provider - - let fsproj = - XmlDocument() in fsproj.Load (projectFile.OpenText()) - - let version = - fsproj.SelectNodes("/Project/ItemGroup") |> - Seq.cast |> - Seq.collect (fun y -> y.SelectNodes("PackageReference") |> Seq.cast) |> - Seq.pick (fun x -> if x.Attributes["Include"].Value = $"Pulumi.{provider}" then - x.Attributes["Version"].Value |> Some - else - None) - - let providerRepositoryNameOverride = - Map.empty - .Add("AzureNative", "azure-native") - - let providerRepository = - providerRepositoryNameOverride |> - Map.tryFind provider |> - Option.defaultValue provider - - loadSchema providerRepository version |> - createTypes |> - createModules provider |> - createNamespace |> - List.singleton |> - Output.Ast - - member this.ValidInputExtensions = seq { ".fs" } \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/IndexModule.fs b/Pulumi.FSharp.Myriad/IndexModule.fs deleted file mode 100644 index b6cf4c0..0000000 --- a/Pulumi.FSharp.Myriad/IndexModule.fs +++ /dev/null @@ -1,136 +0,0 @@ -module IndexModule - -open FSharp.Compiler.Syntax -open AstHelpers -open AstModules -open FSharp.Compiler.Text -open Myriad.Core.Ast -open Myriad.Core.AstExtensions -open Core - -type private Namespace = - { - Name: string - SubNamespaceName: string option - Content: seq - } - -type private SubNamespace = - { - Name: string option - Content: seq - } - -let createModules provider ((indexTypes, qualifiedTypes) : PulumiModule list * PulumiModule list) = - let groupSub contentList = - contentList |> - List.groupBy (fun ns -> ns.SubNamespaceName) |> - List.map (fun (subName, content) -> { Name = subName; Content = content |> Seq.collect (fun c -> c.Content) }) - - let createSubmodule subName rootNamespace content = - createModule' subName [$"{provider}.{rootNamespace}.{subName}" - $"{provider}.Types.Inputs.{rootNamespace}.{subName}"] content - - let createSubmodules rootNamespace = - Seq.collect (function - | { Content = content - SubNamespace.Name = None } -> content - | { Content = content - Name = Some subName } -> seq { createSubmodule subName rootNamespace content }) - - let qualifiedTypesModules = - qualifiedTypes |> - List.map ((fun qualifiedTypeModule -> (String.split '.' qualifiedTypeModule.ResourceProviderNamespace.Value, - qualifiedTypeModule.Content)) >> - (function - | [|rootNamespace|], content -> { Name = rootNamespace - SubNamespaceName = None - Content = content } - | [|rootNamespace; subNamespace|], content -> { Name = rootNamespace - SubNamespaceName = Some subNamespace - Content = content } - | _ -> failwith "Too many nested namespaces")) |> - List.groupBy (fun rootNamespace -> rootNamespace.Name) |> - List.map (fun (rootNamespaceName, content) -> groupSub content |> - createSubmodules rootNamespaceName |> - createModule' rootNamespaceName [$"{provider}.{rootNamespaceName}"]) - - let indexTypesAsts = - indexTypes |> Seq.collect (fun x -> x.Content) - - let letCombineImplementation = - let fromRcd = - SynPat.CreateLongIdent(LongIdentWithDots.CreateString("_combine"),[ - Pat.paren(Pat.tuple(Pat.paren(Pat.tuple("rName", "rArgs")), - Pat.paren(Pat.tuple("lName", "lArgs")))) - ]) |> ignore // Replace below with this - - SynPat.CreateLongIdent(LongIdentWithDots.CreateString("_combine"), [ - SynPat.CreateParen(SynPat.Tuple(false, [ - SynPat.CreateParen(SynPat.Tuple(false, [ SynPat.CreateLongIdent(LongIdentWithDots.CreateString("rName"), []) - SynPat.CreateLongIdent(LongIdentWithDots.CreateString("rArgs"), []) ], range.Zero)) - SynPat.CreateParen(SynPat.Tuple(false, [ SynPat.CreateLongIdent(LongIdentWithDots.CreateString("lName"), []) - SynPat.CreateLongIdent(LongIdentWithDots.CreateString("lArgs"), []) ], range.Zero)) - ], Range.Zero)) - ]) - - let matchExpr = - Expr.paren( - Expr.match'(Expr.tuple(Expr.ident("lName"), Expr.ident("rName")), [ - Match.clause(Pat.tuple(Pat.null', Pat.null'), Expr.null') - Match.clause(Pat.tuple(Pat.null', Pat.ident("name")), Expr.ident("name")) - Match.clause(Pat.tuple(Pat.ident("name"), Pat.null'), Expr.ident("name")) - Match.clause(Pat.wild, Expr.failwith("Duplicate name")) - ])) - - let combineExpr = - Expr.tuple(matchExpr, - Expr.paren(Expr.app("List.concat", (Expr.list [ "lArgs"; "rArgs" ])))) - - let expr = - combineExpr - - SynModuleDecl.CreateLet([ - SynBinding.Let(SynAccess.Private, pattern = fromRcd, expr = expr) - ]) - - let letCombineCrosImplementation = - let fromRcd = - SynPat.CreateLongIdent(LongIdentWithDots.CreateString("_combineCros"),[ - Pat.paren(Pat.tuple(Pat.paren(Pat.tuple("rName", "rArgs", "rCros", "rCroI")), - Pat.paren(Pat.tuple("lName", "lArgs", "lCros", "lCroI")))) - ]) - - let matchExpr argName = - Expr.paren( - Expr.match'(Expr.tuple(Expr.ident("l" + argName), Expr.ident("r" + argName)), [ - Match.clause(Pat.tuple(Pat.null', Pat.null'), Expr.null') - Match.clause(Pat.tuple(Pat.null', Pat.ident(argName.ToLower())), Expr.ident(argName.ToLower())) - Match.clause(Pat.tuple(Pat.ident(argName.ToLower()), Pat.null'), Expr.ident(argName.ToLower())) - Match.clause(Pat.wild, Expr.failwith("Duplicate " + argName)) - ])) - - let combineExpr = - Expr.tuple(matchExpr "Name", - Expr.paren(Expr.app("List.concat", (Expr.list [ "lArgs"; "rArgs" ]))), - Expr.paren(Expr.app("List.concat", (Expr.list [ "lCros"; "rCros" ]))), - matchExpr "CroI") - - let expr = - combineExpr - - SynModuleDecl.CreateLet([ - SynBinding.Let(SynAccess.Private, pattern = fromRcd, expr = expr) - ]) - - Module.module'(provider, [ - Module.open'($"Pulumi.{provider}") - - letCombineImplementation - - letCombineCrosImplementation - - yield! indexTypesAsts - - yield! qualifiedTypesModules - ]) \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Let.fs b/Pulumi.FSharp.Myriad/Let.fs deleted file mode 100644 index f4ad042..0000000 --- a/Pulumi.FSharp.Myriad/Let.fs +++ /dev/null @@ -1,12 +0,0 @@ -module AstLet - -open FSharp.Compiler.Syntax -open FSharp.Compiler.Xml -open Myriad.Core.Ast -open Myriad.Core.AstExtensions - -let createLet name expr (docs : string list) = - SynModuleDecl.CreateLet - [ SynBinding.Let (pattern = SynPat.CreateLongIdent(LongIdentWithDots.CreateString name, []), - expr = expr, - xmldoc = PreXmlDoc.Create(docs)) ] \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Member.fs b/Pulumi.FSharp.Myriad/Member.fs deleted file mode 100644 index 628f98c..0000000 --- a/Pulumi.FSharp.Myriad/Member.fs +++ /dev/null @@ -1,61 +0,0 @@ -module AstMember - -open FSharp.Compiler.Syntax -open FSharp.Compiler.SyntaxTrivia -open FSharp.Compiler.Text -open Core -open FSharp.Compiler.Xml -open Myriad.Core.Ast -open Myriad.Core.AstExtensions - -let createMember' xmlDoc this name args attrs expr = - - //let memberFlags : MemberFlags = - //let b : SynBindingRcd = - // { - // ValData = SynValData(Some memberFlags, SynValInfo([], SynArgInfo(SynAttributes.Empty, false, None)), None) - // Pat = SynPat.LongIdent(LongIdentWithDots([mkId "x"; mkId "Points"], [range.Zero]), None, None, SynConstructorArgs.Pats[], None, range.Zero) - // } - let memberFlag : SynMemberFlags = - { - IsInstance = true - IsDispatchSlot = false - IsOverrideOrExplicitImpl = false - IsFinal = false - MemberKind = SynMemberKind.Member - Trivia = { - MemberRange = Some Range.Zero - OverrideRange = None - AbstractRange = None - StaticRange = None - DefaultRange = None - } - } - - let argsPat = - match args with - | SynPat.Paren _ - | SynPat.Wild _ -> args - | _ -> SynPat.Paren(args, Range.Zero) - - SynBinding.SynBinding(None, - SynBindingKind.Normal, - false, - false, - attrs, - (match xmlDoc with | Some x -> x | None -> PreXmlDoc.Empty), - SynValData.SynValData(Some memberFlag, SynValInfo([], SynArgInfo(SynAttributes.Empty, false, None))(*SynValInfo.Empty*), None), - SynPat.CreateLongIdent(LongIdentWithDots.CreateString(this + "." + name), [argsPat]), - None, - expr, - Range.Zero, - DebugPointAtBinding.NoneAtInvisible, - { LetKeyword = Some Range.Zero - EqualsRange = Some Range.Zero }) - |> fun x -> SynMemberDefn.Member(x, Range.Zero) - -let createMember'' xmlDoc = - createMember' xmlDoc "_" - -let createMember = - createMember' None "_" \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Namespace.fs b/Pulumi.FSharp.Myriad/Namespace.fs deleted file mode 100644 index 1a28400..0000000 --- a/Pulumi.FSharp.Myriad/Namespace.fs +++ /dev/null @@ -1,11 +0,0 @@ -module AstNamespace - -open AstHelpers - -let createNamespace module' = - Namespace.namespace'("Pulumi.FSharp", [ - Module.open'("Pulumi.FSharp") - Module.open'("Pulumi") - - module' - ]) \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Operations.fs b/Pulumi.FSharp.Myriad/Operations.fs deleted file mode 100644 index 482f60d..0000000 --- a/Pulumi.FSharp.Myriad/Operations.fs +++ /dev/null @@ -1,334 +0,0 @@ -module AstOperations - -open FSharp.Compiler.Syntax -open FSharp.Compiler.Xml -open AstAttribute -open AstHelpers -open AstMember -open Myriad.Core.AstExtensions -open Myriad.Core.Ast -open Core - -let private createPatternTyped name args (typeName : string) = - SynPat.CreateTyped(SynPat.CreateLongIdent(LongIdentWithDots.CreateString(name), args), - SynType.CreateLongIdent(typeName)) - -let private createTuple items withParen = - if withParen then - SynPat.CreateParen(SynPat.CreateTuple(items)) - else - SynPat.CreateTuple(items) - -let private argsPattern = - createPattern "args" [] - -let private crosPattern = - createPattern "cros" [] - -let private croIPattern = - createPattern "croI" [] - -let private nPattern = - createPattern "n" [] - -let private namePattern = - createPattern "name" [] - -let createPatternFromCache nameVarName = - match nameVarName with - | "n" -> nPattern - | "name" -> namePattern - | _ -> createPattern nameVarName [] - -let argsTuple' isResource nameVarName withParen = - let nvn = - match nameVarName with - | null -> SynPat.CreateWild - | _ -> createPatternFromCache nameVarName - - createTuple [ nvn - argsPattern - if isResource - then - crosPattern - croIPattern ] withParen - -let argsTupleResource withParen = - createTuple [ namePattern - argsPattern - crosPattern - croIPattern ] withParen - -let argsTupleType withParen = - createTuple [ SynPat.CreateWild - argsPattern ] withParen - -let private createOperation'' isResource (xmlDoc : string list) nameVarName name coName argName hasAttribute typ = - let attributes = - if hasAttribute then - [ createAttributeWithArg "CustomOperation" coName ] - else - [] - - let patterns = - createTuple [ - argsTuple' isResource nameVarName true - match typ with | None -> createPattern argName [] | Some typ -> createPatternTyped argName [] typ - ] true - - let doc = - PreXmlDoc.Create(xmlDoc) |> Some - - createMember'' doc name patterns attributes - -let createNameOperation newNameExpr = - createOperation'' true ["Pulumi logical resource name"] null "Name" "name" "newName" true None newNameExpr - -let private listCons = - Expr.appTuple("List.Cons", [ "apply"; "args" ]) - -let private nReturnTuple = - Expr.tuple(Expr.ident("n"), listCons) - -let private nameReturnTuple = - Expr.tuple(Expr.ident("name"), listCons) - -let private argsIdent = - Expr.ident("args") - -let private inputIdent = - Expr.ident("input") - -let private ioIdent = - Expr.ident("io") - -let private inputListIdent = - Expr.ident("inputList") - -let private inputMapIdent = - Expr.ident("inputMap") - -let private inputJson = - Expr.longIdent("Pulumi.InputJson.op_Implicit") - -let private resourceNameIdent = - Expr.ident("resourceName") - -let private resourceTypeIdent = - Expr.ident("resourceType") - -let private compose = - Expr.paren(Expr.ident("op_ComposeRight")) - -let private inputListFromSeqOf (expr : SynExpr) = - Expr.paren( - Expr.app(compose, [ - Expr.paren(Expr.app(Expr.longIdent("Seq.map"), expr)) - inputListIdent - ]) - ) - -let private inputMapFromMapOf (expr : SynExpr) = - let mapSelector = - Expr.paren( - Expr.lambda([ SimplePat.id("k") - SimplePat.id("v") ], - Expr.tuple(Expr.ident("k"), - Expr.app(expr, - Expr.ident("v"))))) - - Expr.paren( - Expr.app(compose, [ - Expr.paren(Expr.app(Expr.longIdent("Seq.map"), mapSelector)) - inputMapIdent - ]) - ) - -let private inputMapFromMapOfInput = - inputMapFromMapOf inputIdent - -let private inputMapFromMapOfOutput = - inputMapFromMapOf ioIdent - -let private inputListFromSeq = - inputListFromSeqOf inputIdent - -let private inputListFromOutputSeq = - inputListFromSeqOf ioIdent - -let private inputListFromItemOf (expr : SynExpr) = - Expr.paren(Expr.app(compose, - Expr.app(Expr.paren(Expr.app(compose, - [ expr; Expr.longIdent("Seq.singleton") ])), inputListIdent))) - -let private inputListFromItem = - inputListFromItemOf inputIdent - -let private inputListFromOutput = - inputListFromItemOf ioIdent - -let private inputUnion1Of2 = - Expr.ident("inputUnion1Of2") - -let private inputUnion2Of2 = - Expr.ident("inputUnion2Of2") - -let private idIdent = - Expr.ident("id") - -type PType = - | PArray of PType - | PUnion of PType * PType - | PString - | PInteger - | PFloat - | PBoolean - | PMap of PType - | PJson - | PAssetOrArchive - | PArchive - | PAny - | PRef of string - -type Deprecation = - | Current - | Deprecated of string - -type PTypeDefinition = - { - Name: string - Type: PType - Description: string - Deprecation: Deprecation - CanGenerateYield: bool - IsResource: bool - OperationName: string - } - -// This should be the same as the member arg (currently "n") -let private returnTupleCache argsType pType opName setRight = - let set = - Expr.set($"args.{pType.Name}", setRight) - - let lambdaExpr = - Expr.sequential([ - set - Expr.ident("args") - ]) - - let lambda = - Expr.lambda([ - SimplePat.typed("args", argsType) - ], lambdaExpr) - - let consArg = - Expr.paren(Expr.tuple(Expr.paren(lambda), Expr.ident("args"))) - - let cons = - Expr.app(Expr.longIdent("List.Cons"), consArg) - - match pType.IsResource with - | false -> Expr.tuple(Expr.ident("n"), cons) - | true -> Expr.tuple(Expr.ident("name"), cons, Expr.ident("cros"), Expr.ident("croI")) - -let createOperationsFor' argsType pType = - let setRights, argType = - match pType with - | { PTypeDefinition.Type = PString } - | { Type = PInteger } - | { Type = PFloat } - | { Type = PBoolean } -> [ inputIdent; ioIdent ], None - | { Type = PArray _ } -> [ inputListIdent; inputListFromSeq; inputListFromOutputSeq; inputListFromItem; inputListFromOutput ], None - | { Type = PUnion _ } -> [ idIdent; inputUnion1Of2; inputUnion2Of2 ], None - | { Type = PJson } -> [ inputJson ], Some "string" - | { Type = PMap _ } -> [ idIdent; inputMapIdent; inputMapFromMapOfInput; inputMapFromMapOfOutput ], None - | { Type = PRef _ } - | { Type = PArchive } - | { Type = PAny } - | { Type = PAssetOrArchive } -> [ inputIdent ], None - - let snakeCaseName = - if pType.Name = "Name" && pType.IsResource then - "resourceName" - else - toCamelCase pType.Name - - let argName = - match snakeCaseName with - | "fixed" - | "input" - | "args" -> snakeCaseName + "\'" - | "type" -> "resourceType" - | _ -> snakeCaseName - - let operationName = - match pType.Name with - | "Name" when pType.IsResource -> resourceNameIdent - | "Type" when pType.IsResource -> resourceTypeIdent - | _ -> Expr.ident(argName) - - let nameArgName = - if pType.IsResource then - "name" - elif pType.OperationName = "n" then - "nx" - else - "n" - - let memberName = - pType.OperationName |> toPascalCase - - let doc = - String.split '\n' pType.Description |> Array.filter ((=)"" >> not) |> List.ofArray - - let returnTupleCache' = - returnTupleCache argsType pType operationName - - let argNameExpr = - Expr.ident(argName) - - setRights |> - List.map ((fun sr -> Expr.app(sr, argNameExpr)) >> returnTupleCache') |> - List.mapi (fun i e -> createOperation'' pType.IsResource doc nameArgName memberName pType.OperationName argName (i = 0) argType e) - - -let croOperation operationName description argumentName (setAssignmentExpression : SynExpr) withAttribute = - let attributes = - [ if withAttribute then createAttributeWithArg "CustomOperation" (operationName |> toCamelCase) ] - - let patterns = - createTuple [ - argsTupleResource true - createPattern argumentName [] - ] true - - let doc = - PreXmlDoc.Create([ description ]) |> Some - - let updateCrosExpression setAssignmentExpression = - let setExpression = - Expr.set($"cros.{operationName}", setAssignmentExpression) - - let lambdaExpression = - Expr.sequential([ - setExpression - Expr.ident("cros") - ]) - - let listConsLambdaFirstExpression = - Expr.lambda([ - SimplePat.typed("cros", "CustomResourceOptions") - ], lambdaExpression) - - let listConsExpressions = - Expr.paren(Expr.tuple(Expr.paren(listConsLambdaFirstExpression), Expr.ident("cros"))) - - Expr.app(Expr.longIdent("List.Cons"), listConsExpressions) - - let expression = - Expr.tuple(Expr.ident("name"), - Expr.ident("args"), - updateCrosExpression setAssignmentExpression, - Expr.ident("croI")) - - createMember'' doc operationName patterns attributes expression \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Pulumi.FSharp.Myriad.fsproj b/Pulumi.FSharp.Myriad/Pulumi.FSharp.Myriad.fsproj deleted file mode 100644 index f7f9dc6..0000000 --- a/Pulumi.FSharp.Myriad/Pulumi.FSharp.Myriad.fsproj +++ /dev/null @@ -1,51 +0,0 @@ - - - - net6.0 - preview - NU1605,NU1608 - true - Pulumi.FSharp.Myriad - 6.0.* - - - - - true - %(Identity) - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Pulumi.FSharp.Myriad/Run.fs b/Pulumi.FSharp.Myriad/Run.fs deleted file mode 100644 index 2a87dd6..0000000 --- a/Pulumi.FSharp.Myriad/Run.fs +++ /dev/null @@ -1,10 +0,0 @@ -module AstRun - -open AstMember -open AstOperations - -let createRunResource = - createMember "Run" (argsTupleResource true) [] - -let createRunType = - createMember "Run" (argsTupleType true) [] \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Schema.fs b/Pulumi.FSharp.Myriad/Schema.fs deleted file mode 100644 index 5f6d2b7..0000000 --- a/Pulumi.FSharp.Myriad/Schema.fs +++ /dev/null @@ -1,25 +0,0 @@ -module Schema - -open System -open FSharp.Data -open System.IO -open Fantomas - -let private getSchemaFromFileCacheOrDownload provider version schemaUrl = - match FileInfo($"{provider}.{version}.json") with - | fi when fi.Exists -> fi.OpenText().ReadToEnd() - | fi -> let json = Http.RequestString(schemaUrl) - #if DEBUG - use fi = fi.CreateText() in json |> fi.Write - #endif - json - -let private loadSchema' version provider = - $"https://raw.githubusercontent.com/pulumi/pulumi-{provider}/v{version}" + - $"/provider/cmd/pulumi-resource-{provider}/schema.json" |> - getSchemaFromFileCacheOrDownload provider version |> - JsonValue.Parse - -let loadSchema provider version = - String.map Char.ToLower provider |> - loadSchema' version \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/Yield.fs b/Pulumi.FSharp.Myriad/Yield.fs deleted file mode 100644 index f59a20a..0000000 --- a/Pulumi.FSharp.Myriad/Yield.fs +++ /dev/null @@ -1,23 +0,0 @@ -module AstYield - -open AstMember -open FSharp.Compiler.Syntax -open Myriad.Core.Ast -open Myriad.Core.AstExtensions - -let createYield' isType (arg : SynPat) (args : SynExpr) (cros : SynExpr) (croI : SynExpr) = - [ - SynExpr.CreateNull - args - if not isType then - cros - croI - ] |> - SynExpr.CreateTuple |> - createMember "Yield" arg [] - -let createYield isType = - let typedWildcardUnit = - SynPat.CreateTyped(SynPat.CreateWild, SynType.CreateUnit) - - createYield' isType typedWildcardUnit \ No newline at end of file diff --git a/Pulumi.FSharp.NuGet.Test/Program.fs b/Pulumi.FSharp.NuGet.Test/Program.fs deleted file mode 100644 index 8e08e7d..0000000 --- a/Pulumi.FSharp.NuGet.Test/Program.fs +++ /dev/null @@ -1,239 +0,0 @@ -module Program - -open Pulumi.FSharp.Kubernetes.Apps.V1.Inputs -open Pulumi.FSharp.Kubernetes.Core.V1.Inputs -open Pulumi.FSharp.Kubernetes.Meta.V1.Inputs -open Pulumi.FSharp.AzureNative.Compute.Inputs -open Pulumi.FSharp.AzureNative.Network.Inputs -open Pulumi.FSharp.AzureNative.Resources -open Pulumi.FSharp.AzureNative.Storage -open Pulumi.FSharp.AzureNative.Network -open Pulumi.FSharp.AzureNative.Compute -open Pulumi.FSharp.Aws.S3.Inputs -open Pulumi.AzureNative.Storage -open Pulumi.AzureNative.Compute -open Pulumi.FSharp.AzureAD -open Pulumi.FSharp.Outputs -open Pulumi.FSharp.Assets -open Pulumi.FSharp.Aws.S3 -open Pulumi.FSharp.Config -open Pulumi.FSharp - -let deployment = Kubernetes.Apps.V1.deployment -let container = Kubernetes.Core.V1.Inputs.container -let nicSubnet = AzureNative.Network.Inputs.subnet -let sku = AzureNative.Storage.Inputs.sku -let networkProfile = AzureNative.Compute.Inputs.networkProfile -let azureLegacyStorageAccount = Azure.Storage.account - -(* -Backup -$ echo -n "Aws Azure AzureNative AzureAD Kubernetes" | xargs -I{} -n1 -d' ' bash -c 'cp Pulumi.FSharp.{}/Generated.fs $(find Pulumi.FSharp.{} -name "Generated.*.fs")' -Test difference with backup copy: -$ echo -n "Aws Azure AzureNative AzureAD Kubernetes" | xargs -I{} -n1 -d' ' bash -c 'diff -qs $(find Pulumi.FSharp.{} -name "Generated.*.fs") Pulumi.FSharp.{}/Generated.fs' -*) - -let infra () = - deployment { - name "application" - - deploymentSpec { - replicas 1 - - labelSelector { - matchLabels [ "app", "nginx" ] - } - - podTemplateSpec { - objectMeta { - labels [ "app", "nginx" ] - } - - podSpec { - containers [ - container { - name "nginx" - image "nginx" - ports [ containerPort { containerPortValue 80 } ] - } - ] - } - } - } - } - - bucket { - name "bucket-example" - acl "private" - - bucketWebsite { - indexDocument "index.html" - } - } - - group { - name "group-example" - displayName "Example AAD group from Pulumi.FSharp.Extensions" - mailEnabled false - } - - let rg = - resourceGroup { - name "rg-example" - location "West Europe" - } - - azureLegacyStorageAccount { - resourceGroup rg.Name - location rg.Location - name "stlegacyexample" - accountTier "Standard" - accountReplicationType "LRS" - } - - let storage = - storageAccount { - resourceGroup rg.Name - location rg.Location - name "stexample" - sku { name "LRS" } - kind Kind.StorageV2 - } - - let container = - blobContainer { - accountName storage.Name - resourceGroup rg.Name - name "example" - - PublicAccess.None - } - - blob { - name "file-blob" - containerName container.Name - resourceGroup rg.Name - accountName storage.Name - source { Path = "Program.fs" }.ToPulumiType - - BlobType.Block - } - - blob { - name "url-blob" - containerName container.Name - resourceGroup rg.Name - accountName storage.Name - - source { - Uri = "https://raw.githubusercontent.com/UnoSD/Pulumi.FSharp.Extensions/master/README.md" - }.ToPulumiType - - BlobType.Block - } - - blob { - name "archive-blob" - containerName container.Name - resourceGroup rg.Name - accountName storage.Name - - source { - Assets = Map.empty - .Add("pr.fs", File { Path = "Program.fs" }) - .Add("p.txt", String { Text = "text!!!!!!" }) - }.ToPulumiType - - BlobType.Block - } - - let vnet = - virtualNetwork { - name "vnet-example" - location rg.Location - resourceGroup rg.Name - addressSpace { addressPrefixes "10.0.0.0/16" } - dependsOn container - } - - let subnet = - subnet { - name "internal" - resourceGroup rg.Name - virtualNetworkName vnet.Name - addressPrefix "10.0.2.0/24" - } - - let nic = - networkInterface { - name "nic-example" - location rg.Location - resourceGroup rg.Name - - ipConfigurations [ - networkInterfaceIPConfiguration { - name "internal" - privateIPAllocationMethod "Dynamic" - nicSubnet { id subnet.Id } - } - ] - } - - virtualMachine { - name "vm-example" - vmName "vm-example" - location rg.Location - resourceGroup rg.Name - - hardwareProfile { - vmSize "Standard_A1_v2" - } - - networkProfile { - networkInterfaces [ - networkInterfaceReference { id nic.Id } - ] - } - - oSProfile { - adminUsername config["vmUser"] - adminPassword secret["vmPass"] - } - - storageProfile { - oSDisk { - name "osdiskexample" - createOption DiskCreateOptionTypes.FromImage - managedDiskParameters { storageAccountType "Standard_LRS" } - - CachingTypes.ReadWrite - } - - imageReference { - offer "WindowsServer" - publisher "MicrosoftWindowsServer" - sku "2016-Datacenter" - version "latest" - } - } - } - - let privateIp = - output { - let! ipConfigs = nic.IpConfigurations - - return ipConfigs[0].PrivateIPAddress - } - - let secretPipCird = - secretOutput { - let! pip = privateIp - - return $"{pip}/32" - } - - dict [ "VisiblePrivateIP" , privateIp :> obj - "SecretPrivateIPCIDR", secretPipCird :> obj ] - -[] -let main _ = Deployment.run infra diff --git a/Pulumi.FSharp.NuGet.Test/Pulumi.FSharp.NuGet.Test.fsproj b/Pulumi.FSharp.NuGet.Test/Pulumi.FSharp.NuGet.Test.fsproj deleted file mode 100644 index d41161e..0000000 --- a/Pulumi.FSharp.NuGet.Test/Pulumi.FSharp.NuGet.Test.fsproj +++ /dev/null @@ -1,30 +0,0 @@ - - - - Exe - net6.0 - enable - NU1605;NU1608;NU1603;FS0020 - 6.0.* - - - - - - - - - - - - - - - - - - - - - - diff --git a/Pulumi.FSharp.NuGet.Test/Pulumi.test.yaml b/Pulumi.FSharp.NuGet.Test/Pulumi.test.yaml deleted file mode 100644 index a2d570c..0000000 --- a/Pulumi.FSharp.NuGet.Test/Pulumi.test.yaml +++ /dev/null @@ -1,9 +0,0 @@ -encryptionsalt: v1:vC2DnswDsdc=:v1:Yw7Gg1eV2V5gajI4:Z6OMGFCtX8eTeBcpHr+2AZ/qnCE5kg== -config: - aws:region: eu-west-1 - azure-native:location: West Europe - PFETest:vmUser: UnoSD - # export PULUMI_CONFIG_PASSPHRASE='' - # pulumi config set --secret vmPass 'PulumiFsharp99!!' - PFETest:vmPass: - secure: v1:HzkVBijUXi9/c6ZT:QwyDkZ2bZufCkjVh41aBj3Gla4vDIktmZAYbmcZZVNs= \ No newline at end of file diff --git a/Pulumi.FSharp.NuGet.Test/Pulumi.yaml b/Pulumi.FSharp.NuGet.Test/Pulumi.yaml deleted file mode 100644 index 3ce2e4a..0000000 --- a/Pulumi.FSharp.NuGet.Test/Pulumi.yaml +++ /dev/null @@ -1,3 +0,0 @@ -name: PFETest -runtime: dotnet -description: Pulumi.FSharp.Extensions test project diff --git a/Pulumi.FSharp.Random/Myriad.fs b/Pulumi.FSharp.Random/Myriad.fs deleted file mode 100644 index 88da9ab..0000000 --- a/Pulumi.FSharp.Random/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private Random - -module Force = let private nonce = 2071606164 diff --git a/Pulumi.FSharp.Random/Pulumi.FSharp.Random.fsproj b/Pulumi.FSharp.Random/Pulumi.FSharp.Random.fsproj deleted file mode 100644 index 47d60fe..0000000 --- a/Pulumi.FSharp.Random/Pulumi.FSharp.Random.fsproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2021 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi random - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - diff --git a/Pulumi.FSharp.Test/Program.fs b/Pulumi.FSharp.Test/Program.fs deleted file mode 120000 index 5aa63f4..0000000 --- a/Pulumi.FSharp.Test/Program.fs +++ /dev/null @@ -1 +0,0 @@ -../Pulumi.FSharp.NuGet.Test/Program.fs \ No newline at end of file diff --git a/Pulumi.FSharp.Test/Pulumi.FSharp.Test.fsproj b/Pulumi.FSharp.Test/Pulumi.FSharp.Test.fsproj deleted file mode 100644 index 28b2a22..0000000 --- a/Pulumi.FSharp.Test/Pulumi.FSharp.Test.fsproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - Exe - net6.0 - enable - NU1605;NU1608;FS0020 - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Pulumi.FSharp.Test/Pulumi.test.yaml b/Pulumi.FSharp.Test/Pulumi.test.yaml deleted file mode 120000 index 6b8000f..0000000 --- a/Pulumi.FSharp.Test/Pulumi.test.yaml +++ /dev/null @@ -1 +0,0 @@ -../Pulumi.FSharp.NuGet.Test/Pulumi.test.yaml \ No newline at end of file diff --git a/Pulumi.FSharp.Test/Pulumi.yaml b/Pulumi.FSharp.Test/Pulumi.yaml deleted file mode 120000 index 19f249d..0000000 --- a/Pulumi.FSharp.Test/Pulumi.yaml +++ /dev/null @@ -1 +0,0 @@ -../Pulumi.FSharp.NuGet.Test/Pulumi.yaml \ No newline at end of file diff --git a/Pulumi.FSharp.Tls/Myriad.fs b/Pulumi.FSharp.Tls/Myriad.fs deleted file mode 100644 index 0aa51bc..0000000 --- a/Pulumi.FSharp.Tls/Myriad.fs +++ /dev/null @@ -1,3 +0,0 @@ -module private Tls - -module Force = let private nonce = 453776411 \ No newline at end of file diff --git a/Pulumi.FSharp.Tls/Pulumi.FSharp.Tls.fsproj b/Pulumi.FSharp.Tls/Pulumi.FSharp.Tls.fsproj deleted file mode 100644 index 34dd00e..0000000 --- a/Pulumi.FSharp.Tls/Pulumi.FSharp.Tls.fsproj +++ /dev/null @@ -1,57 +0,0 @@ - - - - net6.0 - F# computational expressions to reduce boilerplate in Pulumi code - Copyright 2021 - https://github.com/UnoSD/Pulumi.FSharp.Extensions - GPL-2.0-only - $(MSBuildProjectName) - https://github.com/UnoSD/Pulumi.FSharp.Extensions - fsharp pulumi tls - Stefano d'Antonio (UnoSD) - Stefano d'Antonio (UnoSD) - NU1605,NU1608,FS0058,FS0044 - true - 6.0.* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Myriad.fs - - - - - - - diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..b9f6df4 --- /dev/null +++ b/build.cmd @@ -0,0 +1 @@ +dotnet run --project ./build/build.fsproj -- -t %* diff --git a/build.fsx b/build.fsx deleted file mode 100644 index ae7e678..0000000 --- a/build.fsx +++ /dev/null @@ -1,286 +0,0 @@ -#r "paket: -nuget FSharp.Core 4.7.2 -nuget Fake.DotNet.Cli -nuget Fake.IO.FileSystem -nuget Fake.BuildServer.TeamFoundation -nuget Fake.Core.CommandLineParsing -nuget Newtonsoft.Json -nuget Fake.Core.Xml -nuget Fake.Core.Target //" -#load ".fake/build.fsx/intellisense.fsx" -#nowarn "52" -open Fake.IO.Globbing.Operators -open Fake.Core.TargetOperators -open Fake.DotNet.NuGet -open Fake.BuildServer -open Fake.Net.Http -open Fake.Core.Xml -open Fake.DotNet -open Fake.Core -open System.IO -open Fake.IO -open System - -(* - Usage: - - dotnet fake run build.fsx AzureAD # Install, ForceRegeneration, Pack for AzureAD - dotnet fake run build.fsx AzureAD -t ForceRegeneration # Install and ForceRegeneration only - dotnet fake run build.fsx All -t ForceRegeneration # Install and ForceRegeneration for all providers - dotnet fake run build.fsx All -t Build # Install, ForceRegeneration and Build for all providers -*) - -BuildServer.install [ TeamFoundation.Installer ] - -let args = - Context.forceFakeContext().Arguments |> - Array.ofList |> - Docopt(""" -usage: dotnet_fake_run_build.fsx [PROVIDER] [options] - -options: - -t - """).Parse - -let getTarget args = - match Map.tryFind "-t" args with - | Some (Argument t) -> t - | _ -> "Default" - -let getProvider args = - match Map.tryFind "PROVIDER" args |> - Option.bind (function | Argument p -> Some p | _ -> None) |> - Option.orElse (Environment.environVarOrNone "PROVIDER") |> - Option.orElse (Environment.environVarOrNone "BUILD_DEFINITIONNAME") with - | Some "All" -> "*" - | Some p -> p - | _ -> failwith "Missing provider" - -let getProviders = - function - | "*" -> DirectoryInfo.ofPath "." |> - DirectoryInfo.getSubDirectories |> - Array.filter (fun d -> d.Name.StartsWith("Pulumi.FSharp.") && - not <| d.Name.EndsWith(".Test") && - not <| d.Name.EndsWith(".Core") && - not <| d.Name.EndsWith(".Myriad")) |> - Array.map (fun d -> d.Name.Substring(14)) - | name -> [| name |] - -let getFullName provider = - sprintf "Pulumi.FSharp.%s" provider - -let getProjectFiles provider = - let projectPattern = - provider |> getFullName |> sprintf "**/%s.fsproj" - - !! projectPattern - -let traceNested func projFile = - Trace.useWith true - (fun _ -> func projFile) - (Trace.traceTarget projFile "" "") - // traceTask, traceTag - -let vaultFile = - "Pulumi.FSharp.Extensions.vault.json" - -let nuGetApiKey = - "nuGetApiKey" - -let confirm msg = - printf "%s [y/any]? " msg - Console.ReadKey().Key = ConsoleKey.Y - -Target.create "CreateVault" (fun _ -> - if not <| File.exists vaultFile || - confirm "Vault file exists, do you want to overwrite it" then - - printfn "\nEnter the NuGet API key: " - - let variable : Vault.Variable = { - Name = nuGetApiKey - Secret = false // On Azure DevOps SecureFile is already encrypted - Value = Console.ReadLine() - } - - let vaultFileContent = - //let keyInfo = Some "keyFilePath" |> Vault.createKey - {| - // Only if encrypted - //keyFile = keyInfo.KeyFile - //iv = keyInfo.Iv - values = [| variable |] - |} |> - Newtonsoft.Json.JsonConvert.SerializeObject - - File.WriteAllText(vaultFile, vaultFileContent) -) - -Target.create "Install" (fun _ -> - DotNet.Options.Create() |> - DotNet.install DotNet.Versions.FromGlobalJson |> - ignore -) - -Target.create "ForceRegeneration" (fun _ -> - let myriadFiles = - getProvider args |> - getProviders |> - Seq.map (fun provider -> provider, - (!! (provider |> - getFullName |> - sprintf "**/%s/Myriad.fs")) - |> Seq.exactlyOne) |> - Map.ofSeq - - let random = - DateTime.Now.Millisecond |> - Random - - let moduleDeclaration provider = - sprintf "module private %s" provider - - let forceRebuild = - match BuildServer.isLocalBuild with - | true -> random.Next() |> sprintf "module Force = let private nonce = %i" - | false -> "" - - myriadFiles |> - Map.iter (fun provider myriadFile -> - File.WriteAllText(myriadFile, - sprintf "%s\n\n%s" (moduleDeclaration provider) forceRebuild)) -) - -Target.create "Build" (fun _ -> - let buildOptions options : DotNet.BuildOptions = { - options with - Common = { - options.Common with - Verbosity = Some DotNet.Verbosity.Quiet - } - NoLogo = true - MSBuildParams = { - options.MSBuildParams with - Properties = ("NoRegenerate","true") :: options.MSBuildParams.Properties - } - } - - getProvider args |> - getProviders |> - Array.map (getProjectFiles >> Seq.exactlyOne) |> - Seq.iter (traceNested (DotNet.build buildOptions)) -) - -Target.create "PublishGeneratedCode" (fun _ -> - !! (getProvider args |> getFullName |> sprintf "**/%s/Generated.fs") |> - Seq.iter (Trace.publish ImportData.BuildArtifact) -) - -type NuGetVersions = - { - versions: string[] - } - -Target.create "Pack" (fun _ -> - getProvider args |> - getProviders |> - Seq.iter (fun provider -> - let nextExtensionsVersion = - getFullName provider |> - - // This does not work and returns wrong package - //NuGet.getLatestPackage (NuGet.getRepoUrl()) |> - //(fun x -> x.Version.Split('.')) |> - - // So we have to do this crap... - sprintf "https://www.nuget.org/packages/%s" |> - get "" "" |> - (fun x -> x.Split('\n')) |> - Array.find (fun x -> x.Contains("packageVersion")) |> - (fun x -> x.Split('"')) |> - Array.item 1 |> - (fun x -> x.Split('.')) |> - - Array.last |> - Int32.Parse |> - (+)1 - - let pulumiPackageName = - Map.empty |> - Map.add "AzureNativeV2" "AzureNative" |> - Map.tryFind provider |> - Option.defaultValue provider - - let xPath = - sprintf "/Project/ItemGroup/PackageReference[@Include='Pulumi.%s']" pulumiPackageName - - let projectFile = - getProjectFiles provider |> - Seq.exactlyOne - - let pulumiNuGetVersion = - projectFile |> - loadDoc |> - selectXPathAttributeValue xPath - "Version" - [] - - let packOptions options : DotNet.PackOptions = { - options with - MSBuildParams = { - options.MSBuildParams with - DisableInternalBinLog = true - Properties = - ("PackageVersion", sprintf "%s.%i" pulumiNuGetVersion nextExtensionsVersion) :: - ("NoRegenerate","true") :: - options.MSBuildParams.Properties - } - } - - projectFile |> - traceNested (DotNet.pack packOptions) - ) -) - -Target.create "Push" (fun _ -> - let vaultFile = - Environment.environVarOrNone "FAKEVAULTFILE_SECUREFILEPATH" |> - Option.defaultValue vaultFile |> - FileInfo - - let vault = - match Vault.fromFakeEnvironmentOrNone(), vaultFile.Exists with - | Some vault, _ -> vault - | None , true -> vaultFile.OpenText().ReadToEnd() |> Vault.fromJson - | None , false -> failwith "Unsupported source for secrets" - - let pushOptions options : DotNet.NuGetPushOptions = { - options with - PushParams = { - options.PushParams with - ApiKey = Vault.tryGet nuGetApiKey vault - Source = Some "https://api.nuget.org/v3/index.json" - } - } - - !! (getProvider args |> getFullName |> sprintf "**/%s.*.nupkg") |> - Seq.iter (DotNet.nugetPush pushOptions) -) - -Target.create "Default" ignore - -"Install" =?> -("ForceRegeneration" , BuildServer.isLocalBuild) ==> -"Build" - -"Install" =?> -("ForceRegeneration" , BuildServer.isLocalBuild) ==> -"Pack" =?> -("PublishGeneratedCode", not BuildServer.isLocalBuild) =?> -("Push" , not BuildServer.isLocalBuild) ==> -"Default" - -args |> -getTarget |> -Target.runOrDefaultWithArguments diff --git a/build.fsx.lock b/build.fsx.lock deleted file mode 100644 index 59a7810..0000000 --- a/build.fsx.lock +++ /dev/null @@ -1,239 +0,0 @@ -STORAGE: NONE -RESTRICTION: == netstandard2.0 -NUGET - remote: https://api.nuget.org/v3/index.json - BlackFox.VsWhere (1.1) - FSharp.Core (>= 4.2.3) - Microsoft.Win32.Registry (>= 4.7) - Fake.BuildServer.TeamFoundation (5.20.4) - Fake.Core.Environment (>= 5.20.4) - Fake.Core.String (>= 5.20.4) - Fake.Core.Trace (>= 5.20.4) - Fake.Core.Vault (>= 5.20.4) - Fake.IO.FileSystem (>= 5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Core.CommandLineParsing (5.20.4) - FParsec (>= 1.1.1) - FSharp.Core (>= 4.7.2) - Fake.Core.Context (5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Core.Environment (5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Core.FakeVar (5.20.4) - Fake.Core.Context (>= 5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Core.Process (5.20.4) - Fake.Core.Environment (>= 5.20.4) - Fake.Core.FakeVar (>= 5.20.4) - Fake.Core.String (>= 5.20.4) - Fake.Core.Trace (>= 5.20.4) - Fake.IO.FileSystem (>= 5.20.4) - FSharp.Core (>= 4.7.2) - System.Collections.Immutable (>= 1.7.1) - Fake.Core.SemVer (5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Core.String (5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Core.Target (5.20.4) - Fake.Core.CommandLineParsing (>= 5.20.4) - Fake.Core.Context (>= 5.20.4) - Fake.Core.Environment (>= 5.20.4) - Fake.Core.FakeVar (>= 5.20.4) - Fake.Core.Process (>= 5.20.4) - Fake.Core.String (>= 5.20.4) - Fake.Core.Trace (>= 5.20.4) - FSharp.Control.Reactive (>= 4.4.2) - FSharp.Core (>= 4.7.2) - Fake.Core.Tasks (5.20.4) - Fake.Core.Trace (>= 5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Core.Trace (5.20.4) - Fake.Core.Environment (>= 5.20.4) - Fake.Core.FakeVar (>= 5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Core.Vault (5.20.4) - FSharp.Core (>= 4.7.2) - Newtonsoft.Json (>= 12.0.3) - Fake.Core.Xml (5.20.4) - Fake.Core.String (>= 5.20.4) - FSharp.Core (>= 4.7.2) - Fake.DotNet.Cli (5.20.4) - Fake.Core.Environment (>= 5.20.4) - Fake.Core.Process (>= 5.20.4) - Fake.Core.String (>= 5.20.4) - Fake.Core.Trace (>= 5.20.4) - Fake.DotNet.MSBuild (>= 5.20.4) - Fake.DotNet.NuGet (>= 5.20.4) - Fake.IO.FileSystem (>= 5.20.4) - FSharp.Core (>= 4.7.2) - Mono.Posix.NETStandard (>= 1.0) - Newtonsoft.Json (>= 12.0.3) - Fake.DotNet.MSBuild (5.20.4) - BlackFox.VsWhere (>= 1.1) - Fake.Core.Environment (>= 5.20.4) - Fake.Core.Process (>= 5.20.4) - Fake.Core.String (>= 5.20.4) - Fake.Core.Trace (>= 5.20.4) - Fake.IO.FileSystem (>= 5.20.4) - FSharp.Core (>= 4.7.2) - MSBuild.StructuredLogger (>= 2.1.176) - Fake.DotNet.NuGet (5.20.4) - Fake.Core.Environment (>= 5.20.4) - Fake.Core.Process (>= 5.20.4) - Fake.Core.SemVer (>= 5.20.4) - Fake.Core.String (>= 5.20.4) - Fake.Core.Tasks (>= 5.20.4) - Fake.Core.Trace (>= 5.20.4) - Fake.Core.Xml (>= 5.20.4) - Fake.IO.FileSystem (>= 5.20.4) - Fake.Net.Http (>= 5.20.4) - FSharp.Core (>= 4.7.2) - Newtonsoft.Json (>= 12.0.3) - NuGet.Protocol (>= 5.6) - Fake.IO.FileSystem (5.20.4) - Fake.Core.String (>= 5.20.4) - FSharp.Core (>= 4.7.2) - Fake.Net.Http (5.20.4) - Fake.Core.Trace (>= 5.20.4) - FSharp.Core (>= 4.7.2) - FParsec (1.1.1) - FSharp.Core (>= 4.3.4) - FSharp.Control.Reactive (5.0.2) - FSharp.Core (>= 4.7.2) - System.Reactive (>= 5.0) - FSharp.Core (4.7.2) - Microsoft.Build (16.9) - Microsoft.Build.Framework (16.9) - System.Security.Permissions (>= 4.7) - Microsoft.Build.Tasks.Core (16.9) - Microsoft.Build.Framework (>= 16.9) - Microsoft.Build.Utilities.Core (>= 16.9) - Microsoft.Win32.Registry (>= 4.3) - System.CodeDom (>= 4.4) - System.Collections.Immutable (>= 5.0) - System.Reflection.Metadata (>= 1.6) - System.Reflection.TypeExtensions (>= 4.1) - System.Resources.Extensions (>= 4.6) - System.Runtime.InteropServices (>= 4.3) - System.Security.Cryptography.Pkcs (>= 4.7) - System.Security.Cryptography.Xml (>= 4.7) - System.Security.Permissions (>= 4.7) - System.Threading.Tasks.Dataflow (>= 4.9) - Microsoft.Build.Utilities.Core (16.9) - Microsoft.Build.Framework (>= 16.9) - Microsoft.Win32.Registry (>= 4.3) - System.Collections.Immutable (>= 5.0) - System.Security.Permissions (>= 4.7) - System.Text.Encoding.CodePages (>= 4.0.1) - Microsoft.NETCore.Platforms (5.0.1) - Microsoft.NETCore.Targets (5.0) - Microsoft.Win32.Registry (5.0) - System.Buffers (>= 4.5.1) - System.Memory (>= 4.5.4) - System.Security.AccessControl (>= 5.0) - System.Security.Principal.Windows (>= 5.0) - Mono.Posix.NETStandard (1.0) - MSBuild.StructuredLogger (2.1.364) - Microsoft.Build (>= 16.4) - Microsoft.Build.Framework (>= 16.4) - Microsoft.Build.Tasks.Core (>= 16.4) - Microsoft.Build.Utilities.Core (>= 16.4) - Newtonsoft.Json (13.0.1) - NuGet.Common (5.9) - NuGet.Frameworks (>= 5.9) - NuGet.Configuration (5.9) - NuGet.Common (>= 5.9) - System.Security.Cryptography.ProtectedData (>= 4.4) - NuGet.Frameworks (5.9) - NuGet.Packaging (5.9) - Newtonsoft.Json (>= 9.0.1) - NuGet.Configuration (>= 5.9) - NuGet.Versioning (>= 5.9) - System.Security.Cryptography.Cng (>= 5.0) - System.Security.Cryptography.Pkcs (>= 5.0) - NuGet.Protocol (5.9) - NuGet.Packaging (>= 5.9) - NuGet.Versioning (5.9) - System.Buffers (4.5.1) - System.CodeDom (5.0) - System.Collections.Immutable (5.0) - System.Memory (>= 4.5.4) - System.Formats.Asn1 (5.0) - System.Buffers (>= 4.5.1) - System.Memory (>= 4.5.4) - System.IO (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Text.Encoding (>= 4.3) - System.Threading.Tasks (>= 4.3) - System.Memory (4.5.4) - System.Buffers (>= 4.5.1) - System.Numerics.Vectors (>= 4.4) - System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - System.Numerics.Vectors (4.5) - System.Reactive (5.0) - System.Runtime.InteropServices.WindowsRuntime (>= 4.3) - System.Threading.Tasks.Extensions (>= 4.5.4) - System.Reflection (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.IO (>= 4.3) - System.Reflection.Primitives (>= 4.3) - System.Runtime (>= 4.3) - System.Reflection.Metadata (5.0) - System.Collections.Immutable (>= 5.0) - System.Reflection.Primitives (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Reflection.TypeExtensions (4.7) - System.Resources.Extensions (5.0) - System.Memory (>= 4.5.4) - System.Runtime (4.3.1) - Microsoft.NETCore.Platforms (>= 1.1.1) - Microsoft.NETCore.Targets (>= 1.1.3) - System.Runtime.CompilerServices.Unsafe (5.0) - System.Runtime.Handles (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Runtime.InteropServices (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Reflection (>= 4.3) - System.Reflection.Primitives (>= 4.3) - System.Runtime (>= 4.3) - System.Runtime.Handles (>= 4.3) - System.Runtime.InteropServices.WindowsRuntime (4.3) - System.Runtime (>= 4.3) - System.Security.AccessControl (5.0) - System.Security.Principal.Windows (>= 5.0) - System.Security.Cryptography.Cng (5.0) - System.Security.Cryptography.Pkcs (5.0.1) - System.Buffers (>= 4.5.1) - System.Formats.Asn1 (>= 5.0) - System.Memory (>= 4.5.4) - System.Security.Cryptography.Cng (>= 5.0) - System.Security.Cryptography.ProtectedData (5.0) - System.Memory (>= 4.5.4) - System.Security.Cryptography.Xml (5.0) - System.Memory (>= 4.5.4) - System.Security.Cryptography.Pkcs (>= 5.0) - System.Security.Permissions (>= 5.0) - System.Security.Permissions (5.0) - System.Security.AccessControl (>= 5.0) - System.Security.Principal.Windows (5.0) - System.Text.Encoding (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Text.Encoding.CodePages (5.0) - System.Runtime.CompilerServices.Unsafe (>= 5.0) - System.Threading.Tasks (4.3) - Microsoft.NETCore.Platforms (>= 1.1) - Microsoft.NETCore.Targets (>= 1.1) - System.Runtime (>= 4.3) - System.Threading.Tasks.Dataflow (5.0) - System.Threading.Tasks.Extensions (4.5.4) - System.Runtime.CompilerServices.Unsafe (>= 4.5.3) diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..0783d63 --- /dev/null +++ b/build.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +set -eu +set -o pipefail + +FAKE_DETAILED_ERRORS=true dotnet run --project ./build/build.fsproj -- -t "$@" diff --git a/build/Changelog.fs b/build/Changelog.fs new file mode 100644 index 0000000..2efcb0a --- /dev/null +++ b/build/Changelog.fs @@ -0,0 +1,299 @@ +module Changelog + +open System +open Fake.Core +open Fake.IO + +let isEmptyChange = + function + | Changelog.Change.Added s + | Changelog.Change.Changed s + | Changelog.Change.Deprecated s + | Changelog.Change.Fixed s + | Changelog.Change.Removed s + | Changelog.Change.Security s + | Changelog.Change.Custom(_, s) -> String.IsNullOrWhiteSpace s.CleanedText + +let tagFromVersionNumber versionNumber = sprintf "v%s" versionNumber + +let failOnEmptyChangelog (latestEntry: Changelog.ChangelogEntry) = + let isEmpty = + (latestEntry.Changes + |> Seq.forall isEmptyChange) + || latestEntry.Changes + |> Seq.isEmpty + + if isEmpty then + failwith + "No changes in CHANGELOG. Please add your changes under a heading specified in https://keepachangelog.com/" + +let mkLinkReference + (newVersion: SemVerInfo) + (changelog: Changelog.Changelog) + (gitHubRepoUrl: string) + = + if + changelog.Entries + |> List.isEmpty + then + // No actual changelog entries yet: link reference will just point to the Git tag + sprintf + "[%s]: %s/releases/tag/%s" + newVersion.AsString + (gitHubRepoUrl.TrimEnd('/')) + (tagFromVersionNumber newVersion.AsString) + else + let versionTuple version = + (version.Major, version.Minor, version.Patch) + // Changelog entries come already sorted, most-recent first, by the Changelog module + let prevEntry = + changelog.Entries + |> List.skipWhile (fun entry -> + entry.SemVer.PreRelease.IsSome + || versionTuple entry.SemVer = versionTuple newVersion + ) + |> List.tryHead + + let linkTarget = + match prevEntry with + | Some entry -> + sprintf + "%s/compare/%s...%s" + gitHubRepoUrl + (tagFromVersionNumber entry.SemVer.AsString) + (tagFromVersionNumber newVersion.AsString) + | None -> + sprintf + "%s/releases/tag/%s" + gitHubRepoUrl + (tagFromVersionNumber newVersion.AsString) + + sprintf "[%s]: %s" newVersion.AsString linkTarget + +let mkReleaseNotes changelog (latestEntry: Changelog.ChangelogEntry) gitHubRepoUrl = + let linkReference = mkLinkReference latestEntry.SemVer changelog gitHubRepoUrl + + if String.isNullOrEmpty linkReference then + latestEntry.ToString() + else + // Add link reference target to description before building release notes, since in main changelog file it's at the bottom of the file + let description = + match latestEntry.Description with + | None -> linkReference + | Some desc when desc.Contains(linkReference) -> desc + | Some desc -> sprintf "%s\n\n%s" (desc.Trim()) linkReference + + { + latestEntry with + Description = Some description + } + .ToString() + +let getVersionNumber envVarName ctx = + let args = ctx.Context.Arguments + + let verArg = + args + |> List.tryHead + |> Option.defaultWith (fun () -> Environment.environVarOrDefault envVarName "") + + if SemVer.isValid verArg then + verArg + elif + verArg.StartsWith("v") + && SemVer.isValid verArg.[1..] + then + let target = ctx.Context.FinalTarget + + Trace.traceImportantfn + "Please specify a version number without leading 'v' next time, e.g. \"./build.sh %s %s\" rather than \"./build.sh %s %s\"" + target + verArg.[1..] + target + verArg + + verArg.[1..] + elif String.isNullOrEmpty verArg then + let target = ctx.Context.FinalTarget + + Trace.traceErrorfn + "Please specify a version number, either at the command line (\"./build.sh %s 1.0.0\") or in the %s environment variable" + target + envVarName + + failwith "No version number found" + else + Trace.traceErrorfn + "Please specify a valid version number: %A could not be recognized as a version number" + verArg + + failwith "Invalid version number" + +let mutable changelogBackupFilename = "" + +let updateChangelog changelogPath (changelog: Fake.Core.Changelog.Changelog) gitHubRepoUrl ctx = + + let verStr = + ctx + |> getVersionNumber "RELEASE_VERSION" + + let description, unreleasedChanges = + match changelog.Unreleased with + | None -> None, [] + | Some u -> u.Description, u.Changes + + let newVersion = SemVer.parse verStr + + changelog.Entries + |> List.tryFind (fun entry -> entry.SemVer = newVersion) + |> Option.iter (fun entry -> + Trace.traceErrorfn + "Version %s already exists in %s, released on %s" + verStr + changelogPath + (if entry.Date.IsSome then + entry.Date.Value.ToString("yyyy-MM-dd") + else + "(no date specified)") + + failwith "Can't release with a duplicate version number" + ) + + changelog.Entries + |> List.tryFind (fun entry -> entry.SemVer > newVersion) + |> Option.iter (fun entry -> + Trace.traceErrorfn + "You're trying to release version %s, but a later version %s already exists, released on %s" + verStr + entry.SemVer.AsString + (if entry.Date.IsSome then + entry.Date.Value.ToString("yyyy-MM-dd") + else + "(no date specified)") + + failwith "Can't release with a version number older than an existing release" + ) + + let versionTuple version = + (version.Major, version.Minor, version.Patch) + + let prereleaseEntries = + changelog.Entries + |> List.filter (fun entry -> + entry.SemVer.PreRelease.IsSome + && versionTuple entry.SemVer = versionTuple newVersion + ) + + let prereleaseChanges = + prereleaseEntries + |> List.collect (fun entry -> + entry.Changes + |> List.filter ( + not + << isEmptyChange + ) + ) + |> List.distinct + + let assemblyVersion, nugetVersion = Changelog.parseVersions newVersion.AsString + + let newEntry = + Changelog.ChangelogEntry.New( + assemblyVersion.Value, + nugetVersion.Value, + Some System.DateTime.Today, + description, + unreleasedChanges + @ prereleaseChanges, + false + ) + + let newChangelog = + Changelog.Changelog.New( + changelog.Header, + changelog.Description, + None, + newEntry + :: changelog.Entries + ) + + // Save changelog to temporary file before making any edits + changelogBackupFilename <- System.IO.Path.GetTempFileName() + + changelogPath + |> Shell.copyFile changelogBackupFilename + + Target.activateFinal "DeleteChangelogBackupFile" + + newChangelog + |> Changelog.save changelogPath + + // Now update the link references at the end of the file + let linkReferenceForLatestEntry = mkLinkReference newVersion changelog gitHubRepoUrl + + let linkReferenceForUnreleased = + sprintf + "[Unreleased]: %s/compare/%s...%s" + gitHubRepoUrl + (tagFromVersionNumber newVersion.AsString) + "HEAD" + + let tailLines = + File.read changelogPath + |> List.ofSeq + |> List.rev + + let isRef (line: string) = + System.Text.RegularExpressions.Regex.IsMatch(line, @"^\[.+?\]:\s?[a-z]+://.*$") + + let linkReferenceTargets = + tailLines + |> List.skipWhile String.isNullOrWhiteSpace + |> List.takeWhile isRef + |> List.rev // Now most recent entry is at the head of the list + + let newLinkReferenceTargets = + match linkReferenceTargets with + | [] -> [ + linkReferenceForUnreleased + linkReferenceForLatestEntry + ] + | first :: rest when + first + |> String.startsWith "[Unreleased]:" + -> + linkReferenceForUnreleased + :: linkReferenceForLatestEntry + :: rest + | first :: rest -> + linkReferenceForUnreleased + :: linkReferenceForLatestEntry + :: first + :: rest + + let blankLineCount = + tailLines + |> Seq.takeWhile String.isNullOrWhiteSpace + |> Seq.length + + let linkRefCount = + linkReferenceTargets + |> List.length + + let skipCount = + blankLineCount + + linkRefCount + + let updatedLines = + List.rev ( + tailLines + |> List.skip skipCount + ) + @ newLinkReferenceTargets + + File.write false changelogPath updatedLines + + // If build fails after this point but before we commit changes, undo our modifications + Target.activateBuildFailure "RevertChangelog" + + newEntry diff --git a/build/FsDocs.fs b/build/FsDocs.fs new file mode 100644 index 0000000..d69b452 --- /dev/null +++ b/build/FsDocs.fs @@ -0,0 +1,242 @@ +namespace Fake.DotNet + +open Fake.Core +open Fake.IO +open Fake.IO.FileSystemOperators + +/// +/// Contains tasks to interact with fsdocs tool to +/// process F# script files, markdown and for generating API documentation. +/// +[] +module Fsdocs = + + /// + /// Fsdocs build command parameters and options + /// + type BuildCommandParams = { + /// Input directory of content (default: docs) + Input: string option + + /// Project files to build API docs for outputs, defaults to all packable projects + Projects: seq option + + /// Output Directory (default output for build and tmp/watch for watch) + Output: string option + + /// Disable generation of API docs + NoApiDocs: bool option + + /// Evaluate F# fragments in scripts + Eval: bool option + + /// Save images referenced in docs + SaveImages: bool option + + /// Add line numbers + LineNumbers: bool option + + /// Additional substitution parameters for templates + Parameters: seq option + + /// Disable project cracking. + IgnoreProjects: bool option + + /// In API doc generation qualify the output by the collection name, e.g. 'reference/FSharp.Core/...' instead of 'reference/...' . + Qualify: bool option + + /// The tool will also generate documentation for non-public members + NoPublic: bool option + + /// Do not copy default content styles, javascript or use default templates + NoDefaultContent: bool option + + /// Clean the output directory + Clean: bool option + + /// Display version information + Version: bool option + + /// Provide properties to dotnet msbuild, e.g. --properties Configuration=Release Version=3.4 + Properties: string option + + /// Additional arguments passed down as otherflags to the F# compiler when the API is being generated. + /// Note that these arguments are trimmed, this is to overcome a limitation in the command line argument + /// processing. A typical use-case would be to pass an addition assembly reference. + /// Example --fscoptions " -r:MyAssembly.dll" + FscOptions: string option + + /// Fail if docs are missing or can't be generated + Strict: bool option + + /// Source folder at time of component build (<FsDocsSourceFolder>) + SourceFolder: string option + + /// Source repository for github links (<FsDocsSourceRepository>) + SourceRepository: string option + + /// Assume comments in F# code are markdown (<UsesMarkdownComments>) + MdComments: bool option + } with + + /// Parameter default values. + static member Default = { + Input = None + Projects = None + Output = None + NoApiDocs = None + Eval = None + SaveImages = None + LineNumbers = None + Parameters = None + IgnoreProjects = None + Qualify = None + NoPublic = None + NoDefaultContent = None + Clean = None + Version = None + Properties = None + FscOptions = None + Strict = None + SourceFolder = None + SourceRepository = None + MdComments = None + } + + /// + /// Fsdocs watch command parameters and options + /// + type WatchCommandParams = { + /// Do not serve content when watching. + NoServer: bool option + + /// Do not launch a browser window. + NoLaunch: bool option + + /// URL extension to launch http://localhost:/%s. + Open: string option + + /// Port to serve content for http://localhost serving. + Port: int option + + /// Build Commands + BuildCommandParams: BuildCommandParams option + } with + + /// Parameter default values. + static member Default = { + NoServer = None + NoLaunch = None + Open = None + Port = None + BuildCommandParams = None + } + + let internal buildBuildCommandParams (buildParams: BuildCommandParams) = + let buildSubstitutionParameters (subParameters: seq) = + let subParameters = + subParameters + |> Seq.map (fun (key, value) -> (sprintf "%s %s" key value)) + |> String.concat " " + + sprintf "--parameters %s" subParameters + + System.Text.StringBuilder() + |> StringBuilder.appendIfSome buildParams.Input (sprintf "--input %s") + |> StringBuilder.appendIfSome + buildParams.Projects + (fun projects -> + sprintf + "--projects %s" + (projects + |> String.concat " ") + ) + |> StringBuilder.appendIfSome buildParams.Output (sprintf "--output %s") + |> StringBuilder.appendIfSome buildParams.NoApiDocs (fun _ -> "--noapidocs") + |> StringBuilder.appendIfSome buildParams.Eval (fun _ -> "--eval") + |> StringBuilder.appendIfSome buildParams.SaveImages (fun _ -> "--saveimages") + |> StringBuilder.appendIfSome buildParams.LineNumbers (fun _ -> "--linenumbers") + |> StringBuilder.appendIfSome + buildParams.Parameters + (fun parameters -> buildSubstitutionParameters parameters) + |> StringBuilder.appendIfSome buildParams.IgnoreProjects (fun _ -> "--ignoreprojects") + |> StringBuilder.appendIfSome buildParams.Qualify (fun _ -> "--qualify") + |> StringBuilder.appendIfSome buildParams.NoPublic (fun _ -> "--nonpublic") + |> StringBuilder.appendIfSome buildParams.NoDefaultContent (fun _ -> "--nodefaultcontent") + |> StringBuilder.appendIfSome buildParams.Clean (fun _ -> "--clean") + |> StringBuilder.appendIfSome buildParams.Version (fun _ -> "--version") + |> StringBuilder.appendIfSome buildParams.Properties (sprintf "--properties %s") + |> StringBuilder.appendIfSome buildParams.FscOptions (sprintf "--fscoptions %s") + |> StringBuilder.appendIfSome buildParams.Strict (fun _ -> "--strict") + |> StringBuilder.appendIfSome buildParams.SourceFolder (sprintf "--sourcefolder %s") + |> StringBuilder.appendIfSome buildParams.SourceRepository (sprintf "--sourcerepo %s") + |> StringBuilder.appendIfSome buildParams.MdComments (fun _ -> "--mdcomments") + |> StringBuilder.toText + |> String.trim + + let internal buildWatchCommandParams (watchParams: WatchCommandParams) = + System.Text.StringBuilder() + |> StringBuilder.appendIfSome watchParams.NoServer (fun _ -> "--noserver") + |> StringBuilder.appendIfSome watchParams.NoLaunch (fun _ -> "--nolaunch") + |> StringBuilder.appendIfSome watchParams.Open (sprintf "--open %s") + |> StringBuilder.appendIfSome watchParams.Port (sprintf "--port %i") + |> StringBuilder.appendIfSome watchParams.BuildCommandParams buildBuildCommandParams + |> StringBuilder.toText + |> String.trim + + + let cleanCache (workingDirectory) = + Shell.cleanDirs [ + workingDirectory + ".fsdocs" + ] + + /// + /// Build documentation using fsdocs build command + /// + /// + /// Function used to overwrite the dotnetOptions. + /// Function used to overwrite the build command default parameters. + /// + /// + /// + /// Fsdocs.build (fun p -> { p with Clean = Some(true); Strict = Some(true) }) + /// + /// + let build dotnetOptions setBuildParams = + let buildParams = setBuildParams BuildCommandParams.Default + let formattedParameters = buildBuildCommandParams buildParams + + // let dotnetOptions = (fun (buildOptions: DotNet.Options) -> buildOptions) + let result = DotNet.exec dotnetOptions "fsdocs build" formattedParameters + + if + 0 + <> result.ExitCode + then + failwithf "fsdocs build failed with exit code '%d'" result.ExitCode + + /// + /// Watch documentation using fsdocs watch command + /// + /// + /// Function used to overwrite the dotnetOptions. + /// Function used to overwrite the watch command default parameters. + /// + /// + /// + /// Fsdocs.watch (fun p -> { p with Port = Some(3005) }) + /// + /// + let watch dotnetOptions setWatchParams = + let watchParams = setWatchParams WatchCommandParams.Default + let formattedParameters = buildWatchCommandParams watchParams + + // let dotnetOptions = (fun (buildOptions: DotNet.Options) -> buildOptions) + let result = DotNet.exec dotnetOptions "fsdocs watch" formattedParameters + + if + 0 + <> result.ExitCode + then + failwithf "fsdocs watch failed with exit code '%d'" result.ExitCode diff --git a/build/build.fs b/build/build.fs new file mode 100644 index 0000000..01dacf2 --- /dev/null +++ b/build/build.fs @@ -0,0 +1,912 @@ +#nowarn "57" + +open System +open System.IO + +open Argu +open Fake.Api +open Fake.BuildServer +open Fake.Core +open Fake.Core.TargetOperators +open Fake.DotNet +open Fake.IO +open Fake.IO.FileSystemOperators +open Fake.IO.Globbing.Operators +open Fake.Tools +open global.Paket.PackageSources + + +let environVarAsBoolOrDefault varName defaultValue = + let truthyConsts = [ + "1" + "Y" + "YES" + "T" + "TRUE" + ] + + try + let envvar = (Environment.environVar varName).ToUpper() + + truthyConsts + |> List.exists ((=) envvar) + with _ -> + defaultValue + +//----------------------------------------------------------------------------- +// Metadata and Configuration +//----------------------------------------------------------------------------- + +let rootDirectory = + __SOURCE_DIRECTORY__ + ".." + +let productName = "Pulumi.FSharp.Extensions" + +let sln = + rootDirectory + $"{productName}.sln" + +let srcCodeGlob = + !!(rootDirectory + "src/**/*.fs") + ++ (rootDirectory + "src/**/*.fsx") + -- (rootDirectory + "src/**/obj/**/*.fs") + +let testsCodeGlob = + !!(rootDirectory + "tests/**/*.fs") + ++ (rootDirectory + "tests/**/*.fsx") + -- (rootDirectory + "tests/**/obj/**/*.fs") + +let srcDir = + rootDirectory + "src" + +let srcCoreDir = + srcDir + "Pulumi.FSharp.Core" + "Pulumi.FSharp.Core.fsproj" + +let myriadPluginDir = + srcDir + "Pulumi.FSharp.Myriad" + "Pulumi.FSharp.Myriad.fsproj" + +let providersDir = + rootDirectory + "providers" + +let srcGlob = + srcDir + "**/*.??proj" + +let providersGlob = + providersDir + "**/*.??proj" + +let testsGlob = + rootDirectory + "tests/**/*.??proj" + +let srcAndTest = + !!srcGlob + ++ testsGlob + +let distDir = + rootDirectory + "dist" + +let distGlob = + distDir + "*.nupkg" + +let coverageThresholdPercent = 80 + +let coverageReportDir = + rootDirectory + "docs" + "coverage" + + +let docsDir = + rootDirectory + "docs" + +let docsSrcDir = + rootDirectory + "docsSrc" + +let temp = + rootDirectory + "temp" + +let watchDocsDir = + temp + "watch-docs" + + +let gitOwner = "cagyirey" +let gitRepoName = "Pulumi.FSharp.Extensions" + +let gitHubRepoUrl = sprintf "https://github.com/%s/%s/" gitOwner gitRepoName + +let documentationRootUrl = sprintf "https://%s.github.io/%s/" gitOwner gitRepoName + +let releaseBranch = "main" +let readme = "README.md" +let changelogFile = "CHANGELOG.md" + +let READMElink = Uri(Uri(gitHubRepoUrl), $"blob/{releaseBranch}/{readme}") + +let publishUrl = $"https://nuget.pkg.github.com/{gitOwner}/index.json" + +let enableCodeCoverage = environVarAsBoolOrDefault "ENABLE_COVERAGE" false + +let githubToken = Environment.environVarOrNone "GITHUB_TOKEN" + +let nugetToken = Environment.environVarOrNone "GITHUB_TOKEN" // "NUGET_TOKEN" + +let githubPackageSource = + NuGetV3 { + Url = publishUrl + Authentication = + match githubToken with + | Some token -> + Paket.NetUtils.AuthProvider.ofUserPassword { + Username = GitHubActions.Environment.Actor + Password = token + Type = Paket.NetUtils.AuthType.Basic + } + | None -> Paket.AuthService.GetGlobalAuthenticationProvider publishUrl + } + +let githubSHA = Environment.environVarOrNone "GITHUB_SHA" + +let shortGitShubHA = + githubSHA + |> Option.map (fun sha -> sha.[..7]) + +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- + +let isRelease (targets: Target list) = + targets + |> Seq.map (fun t -> t.Name) + |> Seq.exists ((=) "PublishToNuGet") + +let invokeAsync f = async { f () } + +let configuration (targets: Target list) = + let defaultVal = if isRelease targets then "Release" else "Debug" + + match Environment.environVarOrDefault "CONFIGURATION" defaultVal with + | "Debug" -> DotNet.BuildConfiguration.Debug + | "Release" -> DotNet.BuildConfiguration.Release + | config -> DotNet.BuildConfiguration.Custom config + +let failOnBadExitAndPrint (p: ProcessResult) = + if + p.ExitCode + <> 0 + then + p.Errors + |> Seq.iter Trace.traceError + + failwithf "failed with exitcode %d" p.ExitCode + + +let isCI = lazy environVarAsBoolOrDefault "CI" false + +// CI Servers can have bizarre failures that have nothing to do with your code +let rec retryIfInCI times fn = + match isCI.Value with + | true -> + if times > 1 then + try + fn () + with _ -> + retryIfInCI (times - 1) fn + else + fn () + | _ -> fn () + +let failOnWrongBranch () = + if + Git.Information.getBranchName "" + <> releaseBranch + then + failwithf "Not on %s. If you want to release please switch to this branch." releaseBranch + + +module PulumiExtensions = + + let getProviderName projectFile = + (FileInfo projectFile).Name["Pulumi.FSharp.".Length .. ^".fsproj".Length] + + let getProviderVersion providerName = + let dependencies = Paket.Dependencies.Locate() + let providerNameOverride = Map.ofList [ "AzureNativeV2", "AzureNative" ] + + let provider = + providerNameOverride + |> Map.tryFind providerName + |> Option.defaultValue providerName + + dependencies + .GetInstalledPackageModel(Some "Providers", $"Pulumi.{provider}") + .PackageVersion.Normalize() + + let getProviderVersionFromFsproj projectFile = + getProviderName projectFile + |> getProviderVersion + + let isProviderPublished provider = + try + Paket.Dependencies.FindPackageVersions( + rootDirectory, + [ githubPackageSource ], + $"Pulumi.FSharp.{provider}" + ) + with e -> + Array.empty + |> Set.ofArray + |> Set.map (SemVer.parse) + |> Set.contains ( + getProviderVersion provider + |> SemVer.parse + ) + + + let getProviderVersions (lock1: Paket.LockFile) (lock2: Paket.LockFile) = + (lock1.Groups[Paket.Domain.GroupName "Providers"].Resolution + |> Map.toList) + @ (lock2.Groups[Paket.Domain.GroupName "Providers"].Resolution + |> Map.toList) + |> List.groupBy fst + |> List.map (fun (k, v) -> k, List.map snd v) + |> Map.ofList + |> Map.map (fun package versions -> + match versions with + | [ v1; v2 ] -> + (min v1.Version v2.Version, + Some + <| max v1.Version v2.Version) + | [ version ] -> (version.Version, None) + ) + +module NuGet = + + let isPublished project = + let projectFile = FileInfo project + + let changelog: Changelog.Changelog = + projectFile.DirectoryName + "CHANGELOG.md" + |> Changelog.load + + Paket.Dependencies.FindPackageVersions( + rootDirectory, + [ githubPackageSource ], + System.IO.Path.GetFileNameWithoutExtension project + ) + |> Set.ofArray + |> Set.map (SemVer.parse) + |> Set.contains changelog.LatestEntry.SemVer + |> not + + let shouldPublishCore = Lazy<_>.Create(fun () -> isPublished srcCoreDir) + + let shouldPublishMyriadPlugin = + Lazy<_>.Create(fun () -> isPublished myriadPluginDir) + +module dotnet = + let watch cmdParam program args = + DotNet.exec cmdParam (sprintf "watch %s" program) args + + let run cmdParam args = DotNet.exec cmdParam "run" args + + let tool optionConfig command args = + DotNet.exec optionConfig (sprintf "%s" command) args + |> failOnBadExitAndPrint + + let reportgenerator optionConfig args = + tool optionConfig "reportgenerator" args + + let sourcelink optionConfig args = tool optionConfig "sourcelink" args + + let fcswatch optionConfig args = tool optionConfig "fcswatch" args + + let fsharpAnalyzer optionConfig args = + tool optionConfig "fsharp-analyzers" args + + let fantomas args = DotNet.exec id "fantomas" args + +module FSharpAnalyzers = + type Arguments = + | Project of string + | Analyzers_Path of string + | Fail_On_Warnings of string list + | Ignore_Files of string list + | Verbose + + interface IArgParserTemplate with + member s.Usage = "" + +let failOnLocalBuild () = + if not isCI.Value then + failwith "Not on CI. If you want to publish, please use CI." + +let failOnCIBuild () = + if isCI.Value then + failwith "On CI. If you want to run this target, please use a local build." + +let allPublishChecks () = failOnLocalBuild () + +//----------------------------------------------------------------------------- +// Target Implementations +//----------------------------------------------------------------------------- + +/// So we don't require always being on the latest MSBuild.StructuredLogger +let disableBinLog (p: MSBuild.CliArguments) = { p with DisableInternalBinLog = true } + +let clean _ = + [ + "bin" + "temp" + distDir + coverageReportDir + ] + |> Shell.cleanDirs + + !!srcGlob + ++ testsGlob + |> Seq.collect (fun p -> + [ + "bin" + "obj" + ] + |> Seq.map (fun sp -> + IO.Path.GetDirectoryName p + sp + ) + ) + |> Shell.cleanDirs + + [ "paket-files/paket.restore.cached" ] + |> Seq.iter Shell.rm + +let dotnetRestore _ = + [ sln ] + |> Seq.map (fun dir -> + fun () -> + let args = + [] + |> String.concat " " + + DotNet.restore + (fun c -> { + c with + MSBuildParams = disableBinLog c.MSBuildParams + Common = + c.Common + |> DotNet.Options.withCustomParams (Some(args)) + }) + dir + ) + |> Seq.iter (retryIfInCI 10) + +let buildProvider projectFile = + fun (ctx: TargetParameter) -> + let args = [ + $"/p:VersionPrefix={PulumiExtensions.getProviderVersionFromFsproj projectFile}" + //"/p:NoRegenerate=true" + "--no-restore" + ] + + DotNet.build + (fun c -> { + c with + MSBuildParams = disableBinLog c.MSBuildParams + Configuration = configuration (ctx.Context.AllExecutingTargets) + Common = + c.Common + |> DotNet.Options.withAdditionalArgs args + + }) + projectFile + + +let dotnetBuild project = + fun ctx -> + let changelog = + (FileInfo project).DirectoryName + "CHANGELOG.md" + |> Changelog.load + + let latestEntry = changelog.LatestEntry + + // Get release notes with properly-linked version number + let releaseNotes = Changelog.mkReleaseNotes changelog latestEntry gitHubRepoUrl + + let args = [ + sprintf "/p:VersionPrefix=%s" latestEntry.NuGetVersion + //"/p:NoRegenerate=true" + "--no-restore" + ] + + DotNet.build + (fun c -> { + c with + MSBuildParams = disableBinLog c.MSBuildParams + Configuration = configuration (ctx.Context.AllExecutingTargets) + Common = + c.Common + |> DotNet.Options.withAdditionalArgs args + + }) + project + +let fsharpAnalyzers _ = + let argParser = + ArgumentParser.Create(programName = "fsharp-analyzers") + + !!srcGlob + |> Seq.iter (fun proj -> + let args = + [ + FSharpAnalyzers.Analyzers_Path( + rootDirectory + "packages/analyzers" + ) + FSharpAnalyzers.Arguments.Project proj + FSharpAnalyzers.Arguments.Fail_On_Warnings [ "BDH0002" ] + FSharpAnalyzers.Arguments.Ignore_Files [ "*AssemblyInfo.fs" ] + FSharpAnalyzers.Verbose + ] + |> argParser.PrintCommandLineArgumentsFlat + + dotnet.fsharpAnalyzer id args + ) + +let dotnetTest ctx = + let excludeCoverage = + !!testsGlob + |> Seq.map IO.Path.GetFileNameWithoutExtension + |> String.concat "|" + + let isGenerateCoverageReport = + ctx.Context.TryFindTarget("GenerateCoverageReport").IsSome + + let args = [ + "--no-build" + if + enableCodeCoverage + || isGenerateCoverageReport + then + sprintf "/p:AltCover=true" + + if not isGenerateCoverageReport then + sprintf "/p:AltCoverThreshold=%d" coverageThresholdPercent + + sprintf "/p:AltCoverAssemblyExcludeFilter=%s" excludeCoverage + "/p:AltCoverLocalSource=true" + ] + + DotNet.test + (fun c -> { + c with + MSBuildParams = disableBinLog c.MSBuildParams + Configuration = configuration (ctx.Context.AllExecutingTargets) + Common = + c.Common + |> DotNet.Options.withAdditionalArgs args + }) + sln + +let generateCoverageReport _ = + let coverageReports = + !! "tests/**/coverage*.xml" + |> String.concat ";" + + let sourceDirs = + !!srcGlob + |> Seq.map Path.getDirectory + |> String.concat ";" + + let independentArgs = [ + sprintf "-reports:\"%s\"" coverageReports + sprintf "-targetdir:\"%s\"" coverageReportDir + // Add source dir + sprintf "-sourcedirs:\"%s\"" sourceDirs + // Ignore Tests and if AltCover.Recorder.g sneaks in + sprintf "-assemblyfilters:\"%s\"" "-*.Tests;-AltCover.Recorder.g" + sprintf "-Reporttypes:%s" "Html" + ] + + let args = + independentArgs + |> String.concat " " + + dotnet.reportgenerator id args + +let showCoverageReport _ = + failOnCIBuild () + + coverageReportDir + "index.html" + |> Command.ShellCommand + |> CreateProcess.fromCommand + |> Proc.start + |> ignore + + +let watchTests _ = + !!testsGlob + |> Seq.map (fun proj -> + fun () -> + dotnet.watch + (fun opt -> + opt + |> DotNet.Options.withWorkingDirectory (IO.Path.GetDirectoryName proj) + ) + "test" + "" + |> ignore + ) + |> Seq.iter ( + invokeAsync + >> Async.Catch + >> Async.Ignore + >> Async.Start + ) + + printfn "Press Ctrl+C (or Ctrl+Break) to stop..." + + let cancelEvent = + Console.CancelKeyPress + |> Async.AwaitEvent + |> Async.RunSynchronously + + cancelEvent.Cancel <- true + +let packProvider projectFile = + fun (ctx: TargetParameter) -> + let args = [ + $"/p:VersionPrefix={PulumiExtensions.getProviderVersionFromFsproj projectFile}" + ] + + DotNet.pack + (fun (c: DotNet.PackOptions) -> { + c.WithCommon(DotNet.Options.withAdditionalArgs args) with + NoBuild = true + MSBuildParams = disableBinLog c.MSBuildParams + Configuration = configuration (ctx.Context.AllExecutingTargets) + OutputPath = Some distDir + VersionSuffix = + // only use a version suffix on non-primary branches + Option.filter + (fun _ -> + Git.Information.getBranchName "" + <> releaseBranch + ) + shortGitShubHA + + }) + projectFile + +let dotnetPack project = + + fun ctx -> + let changelog = + (FileInfo project).DirectoryName + "CHANGELOG.md" + |> Changelog.load + + let latestEntry = changelog.LatestEntry + + // Get release notes with properly-linked version number + let releaseNotes = Changelog.mkReleaseNotes changelog latestEntry gitHubRepoUrl + + let args = [ + $"/p:VersionPrefix={latestEntry.NuGetVersion}" + $"/p:PackageReleaseNotes=\"{releaseNotes}\"" + ] + + DotNet.pack + (fun c -> { + c with + MSBuildParams = disableBinLog c.MSBuildParams + Configuration = configuration (ctx.Context.AllExecutingTargets) + OutputPath = Some distDir + NoBuild = true + VersionSuffix = + Option.filter + (fun _ -> + Git.Information.getBranchName "" + <> releaseBranch + ) + shortGitShubHA + Common = + c.Common + |> DotNet.Options.withAdditionalArgs args + }) + project + +let sourceLinkTest _ = + !!distGlob + |> Seq.iter (fun nupkg -> dotnet.sourcelink id (sprintf "test %s" nupkg)) + +let publishProvider packageName = + fun (_: TargetParameter) -> + failOnLocalBuild () + failOnWrongBranch () + + let nupkg = + !!(distDir + $"{packageName}.*.nupkg") + |> Seq.exactlyOne + + DotNet.nugetPush + (fun c -> { + c with + PushParams = { + c.PushParams with + ApiKey = + match nugetToken with + | Some s -> nugetToken + | _ -> c.PushParams.ApiKey // assume paket-config was set properly + Source = Some publishUrl + } + }) + nupkg + +let publishToNuget _ = + allPublishChecks () + + !!distGlob + |> Seq.iter ( + DotNet.nugetPush (fun c -> { + c with + PushParams = { + c.PushParams with + ApiKey = + match nugetToken with + | Some s -> nugetToken + | _ -> c.PushParams.ApiKey // assume paket-config was set properly + Source = Some publishUrl + } + }) + ) + +let paketUpdate _ = + failOnWrongBranch () + failOnLocalBuild () + + let dependencies = (Paket.Dependencies.Locate()).DependenciesFile + + let oldLockfile = + (rootDirectory + "paket.lock") + |> Paket.LockFile.LoadFrom + + if + Paket.UpdateProcess.UpdateGroup( + dependencies, + Paket.Domain.GroupName "Providers", + Paket.UpdaterOptions.Default + ) + then + + let modified = + Git.FileStatus.getChangedFilesInWorkingCopy + rootDirectory + (Git.Information.getCurrentSHA1 rootDirectory) + + if Seq.contains (Git.FileStatus.Modified, "paket.lock") modified then + let newLockfile = + (rootDirectory + "paket.lock") + |> Paket.LockFile.LoadFrom + + let packageUpdates = PulumiExtensions.getProviderVersions oldLockfile newLockfile + + let newBranch = $"paket-update-{Git.Information.getCurrentHash ()}" + let prTitle = $"Paket Update for {DateTime.Now}" + + Git.Branches.checkoutNewBranch + rootDirectory + (Git.Information.getBranchName rootDirectory) + newBranch + + Git.Staging.stageFile rootDirectory "paket.lock" + |> ignore + + Git.Commit.exec rootDirectory prTitle + + Git.Branches.pushBranch rootDirectory gitHubRepoUrl newBranch + + let newPR = + Octokit.NewPullRequest(prTitle, newBranch, releaseBranch, Body = prTitle) + + let pr = + GitHub.createClientWithToken (Option.get githubToken) + |> GitHub.createPullRequest gitOwner gitRepoName newPR + |> Async.RunSynchronously + |> Async.RunSynchronously + + let prMergeResult = + Process.shellExec { + Program = "gh" + WorkingDir = rootDirectory + CommandLine = $"pr merge {pr.Number} --squash --auto" + Args = [] + } + + if + prMergeResult + <> 0 + then + failwith $"gh pr merge failed with exit code {prMergeResult}" + else + failwith "Paket update failed. Unable to create PR." + + +let formatCode _ = + let result = dotnet.fantomas $"{srcDir}" + + if not result.OK then + printfn "Errors while formatting all files: %A" result.Messages + +let checkFormatCode ctx = + let result = dotnet.fantomas $"{srcDir} --check" + + if result.ExitCode = 0 then + Trace.log "No files need formatting" + elif result.ExitCode = 99 then + failwith "Some files need formatting, check output for more info" + else + Trace.logf "Errors while formatting: %A" result.Errors + +let initTargets () = + BuildServer.install [ GitHubActions.Installer ] + + /// Defines a dependency - y is dependent on x. Finishes the chain. + let (==>!) x y = + x ==> y + |> ignore + + /// Defines a soft dependency. x must run before y, if it is present, but y does not require x to be run. Finishes the chain. + let (?=>!) x y = + x ?=> y + |> ignore + //----------------------------------------------------------------------------- + // Hide Secrets in Logger + //----------------------------------------------------------------------------- + Option.iter (TraceSecrets.register "") githubToken + Option.iter (TraceSecrets.register "") nugetToken + + //----------------------------------------------------------------------------- + // Target Declaration + //----------------------------------------------------------------------------- + Target.create "Clean" clean + Target.create "DotnetRestore" dotnetRestore + + Target.create "BuildCore" (dotnetBuild srcCoreDir) + Target.create "BuildMyriadPlugin" (dotnetBuild myriadPluginDir) + Target.create "BuildProviders" ignore + + Target.create "DotnetTest" dotnetTest + Target.create "WatchTests" watchTests + + Target.create "FSharpAnalyzers" fsharpAnalyzers + Target.create "GenerateCoverageReport" generateCoverageReport + Target.create "ShowCoverageReport" showCoverageReport + + Target.create "PackCore" (dotnetPack srcCoreDir) + Target.create "PackMyriadPlugin" (dotnetPack myriadPluginDir) + Target.create "DotnetPack" ignore + Target.create "PackProviders" ignore + Target.create "PublishProviders" ignore + Target.create "SourceLinkTest" sourceLinkTest + Target.create "PublishToNuGet" publishToNuget + Target.create "PaketUpdate" paketUpdate + Target.create "FormatCode" formatCode + Target.create "CheckFormatCode" checkFormatCode + Target.create "Publish" ignore //For CI + + !!providersGlob + |> Seq.iter (fun projectFile -> + let providerName = PulumiExtensions.getProviderName projectFile + + Target.create $"BuildProvider.{providerName}" (buildProvider projectFile) + Target.create $"PackProvider.{providerName}" (packProvider projectFile) + + Target.create + $"PublishProvider.{providerName}" + (publishProvider $"Pulumi.FSharp.{providerName}") + + //----------------------------------------------------------------------------- + // Target Dependencies + //----------------------------------------------------------------------------- + + "Clean" + ==>! $"PackProvider.{providerName}" + + "DotnetRestore" + ==>! $"BuildProvider.{providerName}" + + "BuildMyriadPlugin" + ==> $"BuildProvider.{providerName}" + ==> $"PackProvider.{providerName}" + ==>! $"PublishProvider.{providerName}" + + $"BuildProvider.{providerName}" + ==>! "BuildProviders" + + $"PackProvider.{providerName}" + ==>! "PackProviders" + + if not (PulumiExtensions.isProviderPublished providerName) then + $"PublishProvider.{providerName}" + ==>! "PublishProviders" + ) + + // Only call Clean if DotnetPack was in the call chain + // Ensure Clean is called before DotnetRestore + "Clean" + ?=>! "DotnetRestore" + + "Clean" + ==>! "DotnetPack" + + "Clean" + ==>! "PackCore" + + "Clean" + ==>! "PackMyriadPlugin" + + "DotnetTest" + ==> "GenerateCoverageReport" + ==>! "ShowCoverageReport" + + "DotnetRestore" + ==>! "WatchTests" + + + "DotnetRestore" + =?> ("CheckFormatCode", isCI.Value) + ==> "BuildCore" + ==> "DotnetTest" + =?> ("PackCore", NuGet.shouldPublishCore.Value) + ==> "PublishToNuGet" + ==>! "Publish" + + "DotnetRestore" + =?> ("CheckFormatCode", isCI.Value) + ==> "BuildMyriadPlugin" + ==> "DotnetTest" + =?> ("PackMyriadPlugin", NuGet.shouldPublishMyriadPlugin.Value) + ==> "PublishToNuGet" + ==>! "Publish" + +//----------------------------------------------------------------------------- +// Target Start +//----------------------------------------------------------------------------- +[] +let main argv = + argv + |> Array.toList + |> Context.FakeExecutionContext.Create false "build.fsx" + |> Context.RuntimeContext.Fake + |> Context.setExecutionContext + + initTargets () + Target.runOrDefaultWithArguments "Publish" + + 0 // return an integer exit code diff --git a/build/build.fsproj b/build/build.fsproj new file mode 100644 index 0000000..86fd643 --- /dev/null +++ b/build/build.fsproj @@ -0,0 +1,16 @@ + + + + Exe + net6.0 + preview + 3390;$(WarnOn) + false + + + + + + + + diff --git a/build/paket.references b/build/paket.references new file mode 100644 index 0000000..dac93c0 --- /dev/null +++ b/build/paket.references @@ -0,0 +1,15 @@ +group Build + Argu + Fake.Api.GitHub + Fake.BuildServer.GitHubActions + Fake.Core.Target + Fake.Core.ReleaseNotes + Fake.Core.Environment + Fake.Core.Process + Fake.DotNet.AssemblyInfoFile + Fake.DotNet.Cli + Fake.DotNet.Paket + Fake.IO.FileSystem + Fake.Tools.Git + Octokit + Paket.Core diff --git a/devcontainer.json b/devcontainer.json new file mode 100644 index 0000000..3f27ab2 --- /dev/null +++ b/devcontainer.json @@ -0,0 +1,73 @@ +{ + "name": "dotnet", + // Set the build context one level higher so we can grab metadata like global.json + "context": "..", + "dockerFile": "Dockerfile", + "forwardPorts": [ + 0 + ], + "features": { + // https://github.com/devcontainers/features/blob/main/src/common-utils/README.md + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": true, + "installOhMyZshConfig": true, + "configureZshAsDefaultShell": true, + "username": "vscode", + "userUid": "1000", + "userGid": "1000", + "upgradePackages": true + }, + // https://github.com/devcontainers/features/blob/main/src/github-cli/README.md + "ghcr.io/devcontainers/features/github-cli:1": {}, + // https://github.com/devcontainers-contrib/features/blob/main/src/starship/README.md + "ghcr.io/devcontainers-contrib/features/starship:1": {}, + // https://github.com/devcontainers/features/blob/main/src/dotnet/README.md + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "7.0", + "additionalVersions": "6.0" + } + }, + "overrideFeatureInstallOrder": [ + "ghcr.io/devcontainers/features/common-utils", + "ghcr.io/devcontainers/features/github-cli", + "ghcr.io/devcontainers-contrib/features/starship", + "ghcr.io/devcontainers/features/dotnet" + ], + "customizations": { + "vscode": { + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-dotnettools.csharp", + "Ionide.Ionide-fsharp", + "tintoy.msbuild-project-tools", + "ionide.ionide-paket", + "usernamehw.errorlens", + "alefragnani.Bookmarks", + "oderwat.indent-rainbow", + "vscode-icons-team.vscode-icons", + "EditorConfig.EditorConfig", + "ms-azuretools.vscode-docker", + "GitHub.vscode-pull-request-github", + "github.vscode-github-actions" + ], + "settings": { + "terminal.integrated.defaultProfile.linux": "zsh", + "csharp.suppressDotnetInstallWarning": true + } + } + }, + "remoteUser": "vscode", + "containerUser": "vscode", + "containerEnv": { + // Expose the local environment variable to the container + // They are used for releasing and publishing from the container + "GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}" + }, + "onCreateCommand": { + "enable-starship": "echo 'eval \"$(starship init zsh)\"' >> ~/.zshrc" + }, + "postAttachCommand": { + "restore": "dotnet tool restore && dotnet restore" + }, + "waitFor": "updateContentCommand" +} \ No newline at end of file diff --git a/fake.cmd b/fake.cmd deleted file mode 100644 index 43536ae..0000000 --- a/fake.cmd +++ /dev/null @@ -1,2 +0,0 @@ -dotnet tool restore -dotnet fake %* \ No newline at end of file diff --git a/fake.sh b/fake.sh deleted file mode 100755 index bc92bc9..0000000 --- a/fake.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -set -eu -set -o pipefail - -dotnet tool restore -dotnet fake "$@" \ No newline at end of file diff --git a/global.json b/global.json index 4052a2d..7fa817c 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,5 @@ { "sdk": { - "version": "6.0.100", - "rollForward": "latestMinor", - "allowPrerelease": true + "version": "8.0.300" } } \ No newline at end of file diff --git a/paket.dependencies b/paket.dependencies new file mode 100644 index 0000000..ef42f11 --- /dev/null +++ b/paket.dependencies @@ -0,0 +1,72 @@ +group Myriad + framework: net6.0 + source https://api.nuget.org/v3/index.json + storage: none + + nuget FSharp.Core ~> 6 + nuget FSharp.Data ~> 6 + nuget FSharp.Text.RegexProvider ~> 2 + nuget Myriad.Core 0.8.1 + nuget Myriad.Sdk 0.8.1 + nuget Paket.Core ~> 8 + +group Providers + framework: net8.0 + source https://api.nuget.org/v3/index.json + storage: none + + nuget Pulumi.Aws + nuget Pulumi.Auth0 + nuget Pulumi.Azure + nuget Pulumi.AzureAD + nuget Pulumi.AzureNative + nuget Pulumi.Command + nuget Pulumi.DigitalOcean + nuget Pulumi.Docker + nuget Pulumi.FSharp + nuget Pulumi.FSharp.Core + nuget Pulumi.Gcp + nuget Pulumi.Kubernetes + nuget Pulumi.Random + nuget Pulumi.Tls + +group Main + framework: net8.0 + source https://api.nuget.org/v3/index.json + storage: none + + nuget FSharp.Core ~> 8 + nuget Myriad.Sdk 0.8.1 copy_local: true + nuget Microsoft.SourceLink.GitHub copy_local: true + nuget YoloDev.Expecto.TestSdk + nuget Microsoft.NET.Test.Sdk + nuget altcover + +// [ FAKE GROUP ] +group Build + framework: net6.0 + storage: none + source https://www.nuget.org/api/v2 + source https://api.nuget.org/v3/index.json + nuget Fake.IO.FileSystem + nuget Fake.Core.Target + nuget Fake.Core.ReleaseNotes + nuget Fake.Core.Environment + nuget Fake.DotNet.Cli + nuget Fake.Core.Process + nuget Fake.DotNet.AssemblyInfoFile + nuget Fake.Tools.Git + nuget Fake.DotNet.Paket + nuget Fake.Api.GitHub + nuget Fake.BuildServer.GitHubActions + nuget Argu + nuget Microsoft.Build 17.3.2 + nuget Microsoft.Build.Framework 17.3.2 + nuget Microsoft.Build.Tasks.Core 17.3.2 + nuget Microsoft.Build.Utilities.Core 17.3.2 + nuget Paket.Core ~> 8 + +group Analyzers + source https://www.nuget.org/api/v2 + source https://api.nuget.org/v3/index.json + nuget BinaryDefense.FSharp.Analyzers.Hashing 0.2.2 \ No newline at end of file diff --git a/paket.lock b/paket.lock new file mode 100644 index 0000000..c8312bc --- /dev/null +++ b/paket.lock @@ -0,0 +1,1030 @@ +STORAGE: NONE +RESTRICTION: == net8.0 +NUGET + remote: https://api.nuget.org/v3/index.json + altcover (8.8.74) + Expecto (10.2.1) + FSharp.Core (>= 7.0.200) + Mono.Cecil (>= 0.11.4 < 1.0) + FSharp.Core (8.0.301) + Microsoft.Build.Tasks.Git (8.0) - copy_local: true + Microsoft.CodeCoverage (17.10) + Microsoft.NET.Test.Sdk (17.10) + Microsoft.CodeCoverage (>= 17.10) + Microsoft.TestPlatform.TestHost (>= 17.10) + Microsoft.SourceLink.Common (8.0) - copy_local: true + Microsoft.SourceLink.GitHub (8.0) - copy_local: true + Microsoft.Build.Tasks.Git (>= 8.0) + Microsoft.SourceLink.Common (>= 8.0) + Microsoft.TestPlatform.ObjectModel (17.10) + System.Reflection.Metadata (>= 1.6) + Microsoft.TestPlatform.TestHost (17.10) + Microsoft.TestPlatform.ObjectModel (>= 17.10) + Newtonsoft.Json (>= 13.0.1) + Mono.Cecil (0.11.5) + Myriad.Sdk (0.8.1) - copy_local: true + Newtonsoft.Json (13.0.3) + System.Collections.Immutable (8.0) + System.Reflection.Metadata (8.0) + System.Collections.Immutable (>= 8.0) + YoloDev.Expecto.TestSdk (0.14.3) + Expecto (>= 10.0 < 11.0) + FSharp.Core (>= 7.0.200) + System.Collections.Immutable (>= 6.0) + +GROUP Analyzers +NUGET + remote: https://www.nuget.org/api/v2 + BinaryDefense.FSharp.Analyzers.Hashing (0.2.2) + FSharp.Analyzers.SDK (>= 0.8) - restriction: >= net5.0 + FSharp.Core (>= 5.0.1) - restriction: >= net5.0 + FSharp.Analyzers.SDK (0.16) - restriction: >= net5.0 + FSharp.Compiler.Service (>= 43.7.400) - restriction: >= net6.0 + FSharp.Core (>= 7.0.400) - restriction: >= net6.0 + McMaster.NETCore.Plugins (>= 1.4) - restriction: >= net6.0 + FSharp.Compiler.Service (43.8.301) - restriction: >= net6.0 + FSharp.Core (8.0.301) - restriction: >= netstandard2.0 + System.Buffers (>= 4.5.1) - restriction: >= netstandard2.0 + System.Collections.Immutable (>= 7.0) - restriction: >= netstandard2.0 + System.Diagnostics.DiagnosticSource (>= 7.0.2) - restriction: >= netstandard2.0 + System.Memory (>= 4.5.5) - restriction: >= netstandard2.0 + System.Reflection.Emit (>= 4.7) - restriction: >= netstandard2.0 + System.Reflection.Metadata (>= 7.0) - restriction: >= netstandard2.0 + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: >= netstandard2.0 + FSharp.Core (8.0.301) - restriction: >= net5.0 + McMaster.NETCore.Plugins (1.4) - restriction: >= net6.0 + Microsoft.DotNet.PlatformAbstractions (>= 3.1.6) - restriction: >= netcoreapp2.1 + Microsoft.Extensions.DependencyModel (>= 5.0) - restriction: >= netcoreapp2.1 + Microsoft.DotNet.PlatformAbstractions (3.1.6) - restriction: >= net6.0 + Microsoft.Extensions.DependencyModel (8.0.1) - restriction: >= net6.0 + System.Text.Encodings.Web (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) + System.Text.Json (>= 8.0.4) - restriction: || (>= net462) (>= netstandard2.0) + System.Buffers (4.5.1) - restriction: >= net6.0 + System.Collections.Immutable (8.0) - restriction: >= net6.0 + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0)) + System.Diagnostics.DiagnosticSource (8.0.1) - restriction: >= net6.0 + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0)) + System.Memory (4.5.5) - restriction: >= net6.0 + System.Buffers (>= 4.5.1) - restriction: || (&& (>= monoandroid) (< netstandard1.1)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (>= monotouch) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (< uap10.1) (>= wpa81)) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos) + System.Runtime.CompilerServices.Unsafe (>= 4.5.3) - restriction: || (&& (>= monoandroid) (< netstandard1.1)) (&& (< monoandroid) (< net45) (>= netstandard1.1) (< netstandard2.0) (< win8) (< wpa81)) (&& (< monoandroid) (>= netcoreapp2.0) (< netcoreapp2.1)) (&& (< monoandroid) (< netstandard1.1) (>= portable-net45+win8+wpa81) (< win8)) (>= monotouch) (&& (>= net45) (< netstandard2.0)) (&& (< net45) (< netcoreapp2.0) (>= netstandard2.0)) (>= net461) (&& (< netstandard1.1) (>= win8)) (&& (< netstandard2.0) (>= wpa81)) (>= uap10.1) (>= xamarinios) (>= xamarinmac) (>= xamarintvos) (>= xamarinwatchos) + System.Reflection.Emit (4.7) - restriction: >= net6.0 + System.Reflection.Metadata (8.0) - restriction: >= net6.0 + System.Collections.Immutable (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) + System.Runtime.CompilerServices.Unsafe (6.0) - restriction: >= net6.0 + System.Text.Encodings.Web (8.0) - restriction: >= net6.0 + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0)) + System.Text.Json (8.0.4) - restriction: >= net6.0 + System.Runtime.CompilerServices.Unsafe (>= 6.0) - restriction: || (>= net462) (&& (>= net6.0) (< net7.0)) (&& (< net6.0) (>= netstandard2.0)) + System.Text.Encodings.Web (>= 8.0) - restriction: || (>= net462) (>= netstandard2.0) + +GROUP Build +STORAGE: NONE +RESTRICTION: == net6.0 +NUGET + remote: https://www.nuget.org/api/v2 + Argu (6.2.3) + FSharp.Core (>= 4.3.2) + System.Configuration.ConfigurationManager (>= 4.4) + BlackFox.VsWhere (1.1) + FSharp.Core (>= 4.2.3) + Microsoft.Win32.Registry (>= 4.7) + Chessie (0.6) + FSharp.Core (>= 4.0.1.7-alpha) + NETStandard.Library (>= 1.6) + Fake.Api.GitHub (6.0) + FSharp.Core (>= 6.0.3) + Octokit (>= 0.50) + Fake.BuildServer.GitHubActions (6.0) + Fake.Core.Environment (>= 6.0) + Fake.Core.Trace (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.CommandLineParsing (6.0) + FParsec (>= 1.1.1) + FSharp.Core (>= 6.0.3) + Fake.Core.Context (6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.Environment (6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.FakeVar (6.0) + Fake.Core.Context (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.Process (6.0) + Fake.Core.Environment (>= 6.0) + Fake.Core.FakeVar (>= 6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Trace (>= 6.0) + Fake.IO.FileSystem (>= 6.0) + FSharp.Core (>= 6.0.3) + System.Collections.Immutable (>= 6.0) + Fake.Core.ReleaseNotes (6.0) + Fake.Core.SemVer (>= 6.0) + Fake.Core.String (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.SemVer (6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.String (6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.Target (6.0) + Fake.Core.CommandLineParsing (>= 6.0) + Fake.Core.Context (>= 6.0) + Fake.Core.Environment (>= 6.0) + Fake.Core.FakeVar (>= 6.0) + Fake.Core.Process (>= 6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Trace (>= 6.0) + FSharp.Control.Reactive (>= 5.0.2) + FSharp.Core (>= 6.0.3) + Fake.Core.Tasks (6.0) + Fake.Core.Trace (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.Trace (6.0) + Fake.Core.Environment (>= 6.0) + Fake.Core.FakeVar (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.Core.Xml (6.0) + Fake.Core.String (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.DotNet.AssemblyInfoFile (6.0) + Fake.Core.Environment (>= 6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Trace (>= 6.0) + Fake.IO.FileSystem (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.DotNet.Cli (6.0) + Fake.Core.Environment (>= 6.0) + Fake.Core.Process (>= 6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Trace (>= 6.0) + Fake.DotNet.MSBuild (>= 6.0) + Fake.DotNet.NuGet (>= 6.0) + Fake.IO.FileSystem (>= 6.0) + FSharp.Core (>= 6.0.3) + Mono.Posix.NETStandard (>= 1.0) + Newtonsoft.Json (>= 13.0.1) + Fake.DotNet.MSBuild (6.0) + BlackFox.VsWhere (>= 1.1) + Fake.Core.Environment (>= 6.0) + Fake.Core.Process (>= 6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Trace (>= 6.0) + Fake.IO.FileSystem (>= 6.0) + FSharp.Core (>= 6.0.3) + MSBuild.StructuredLogger (>= 2.1.545) + Fake.DotNet.NuGet (6.0) + Fake.Core.Environment (>= 6.0) + Fake.Core.Process (>= 6.0) + Fake.Core.SemVer (>= 6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Tasks (>= 6.0) + Fake.Core.Trace (>= 6.0) + Fake.Core.Xml (>= 6.0) + Fake.IO.FileSystem (>= 6.0) + Fake.Net.Http (>= 6.0) + FSharp.Core (>= 6.0.3) + Newtonsoft.Json (>= 13.0.1) + NuGet.Protocol (>= 6.0) + Fake.DotNet.Paket (6.0) + Fake.Core.Process (>= 6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Trace (>= 6.0) + Fake.DotNet.Cli (>= 6.0) + Fake.IO.FileSystem (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.IO.FileSystem (6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Trace (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.Net.Http (6.0) + Fake.Core.Trace (>= 6.0) + FSharp.Core (>= 6.0.3) + Fake.Tools.Git (6.0) + Fake.Core.Environment (>= 6.0) + Fake.Core.Process (>= 6.0) + Fake.Core.SemVer (>= 6.0) + Fake.Core.String (>= 6.0) + Fake.Core.Trace (>= 6.0) + Fake.IO.FileSystem (>= 6.0) + FSharp.Core (>= 6.0.3) + FParsec (1.1.1) + FSharp.Core (>= 4.3.4) + FSharp.Control.Reactive (5.0.5) + FSharp.Core (>= 4.7.2) + System.Reactive (>= 5.0 < 6.0) + FSharp.Core (6.0.3) + Microsoft.Build (17.3.2) + Microsoft.Build.Framework (>= 17.3.2) + Microsoft.NET.StringTools (>= 17.3.2) + System.Collections.Immutable (>= 6.0) + System.Configuration.ConfigurationManager (>= 6.0) + System.Reflection.Metadata (>= 6.0) + System.Reflection.MetadataLoadContext (>= 6.0) + System.Security.Principal.Windows (>= 5.0) + System.Text.Encoding.CodePages (>= 6.0) + System.Text.Json (>= 6.0) + System.Threading.Tasks.Dataflow (>= 6.0) + Microsoft.Build.Framework (17.3.2) + System.Security.Permissions (>= 6.0) + Microsoft.Build.Tasks.Core (17.3.2) + Microsoft.Build.Framework (>= 17.3.2) + Microsoft.Build.Utilities.Core (>= 17.3.2) + Microsoft.NET.StringTools (>= 17.3.2) + System.CodeDom (>= 6.0) + System.Collections.Immutable (>= 6.0) + System.Reflection.Metadata (>= 6.0) + System.Resources.Extensions (>= 6.0) + System.Security.Cryptography.Pkcs (>= 6.0.1) + System.Security.Cryptography.Xml (>= 6.0) + System.Security.Permissions (>= 6.0) + System.Threading.Tasks.Dataflow (>= 6.0) + Microsoft.Build.Utilities.Core (17.3.2) + Microsoft.Build.Framework (>= 17.3.2) + Microsoft.NET.StringTools (>= 17.3.2) + System.Collections.Immutable (>= 6.0) + System.Configuration.ConfigurationManager (>= 6.0) + Microsoft.NET.StringTools (17.10.4) + System.Memory (>= 4.5.5) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + Microsoft.NETCore.Platforms (7.0.4) + Microsoft.NETCore.Targets (5.0) + Microsoft.Win32.Registry (5.0) + System.Security.AccessControl (>= 5.0) + System.Security.Principal.Windows (>= 5.0) + Mono.Cecil (0.11.5) + Mono.Posix.NETStandard (1.0) + MSBuild.StructuredLogger (2.1.815) + Microsoft.Build.Framework (>= 16.10) + Microsoft.Build.Utilities.Core (>= 16.10) + NETStandard.Library (2.0.3) + Microsoft.NETCore.Platforms (>= 1.1) + Newtonsoft.Json (13.0.3) + NuGet.Common (6.10.1) + NuGet.Frameworks (>= 6.10.1) + NuGet.Configuration (6.10.1) + NuGet.Common (>= 6.10.1) + System.Security.Cryptography.ProtectedData (>= 4.4) + NuGet.Frameworks (6.10.1) + NuGet.Packaging (6.10.1) + Newtonsoft.Json (>= 13.0.3) + NuGet.Configuration (>= 6.10.1) + NuGet.Versioning (>= 6.10.1) + System.Security.Cryptography.Pkcs (>= 6.0.4) + NuGet.Protocol (6.10.1) + NuGet.Packaging (>= 6.10.1) + NuGet.Versioning (6.10.1) + Octokit (13.0.1) + Paket.Core (8.0.3) + Chessie (>= 0.6) + FSharp.Core (6.0.3) + Mono.Cecil (>= 0.11.3 < 0.12) + Newtonsoft.Json (>= 13.0.1) + NuGet.Packaging (>= 5.9.1) + System.Net.Http (>= 4.3.4) + System.Net.Http.WinHttpHandler (>= 5.0) + System.Security.Cryptography.ProtectedData (>= 5.0) + runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.native.System (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + runtime.native.System.Net.Http (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + runtime.native.System.Security.Cryptography.Apple (4.3.1) + runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) + runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (4.3.1) + runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + System.CodeDom (8.0) + System.Collections (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Collections.Concurrent (4.3) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.Diagnostics.Tracing (>= 4.3) + System.Globalization (>= 4.3) + System.Reflection (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Threading (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.Collections.Immutable (8.0) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Configuration.ConfigurationManager (8.0) + System.Security.Cryptography.ProtectedData (>= 8.0) + System.Diagnostics.Debug (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Diagnostics.DiagnosticSource (8.0.1) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Diagnostics.Tracing (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Formats.Asn1 (8.0.1) + System.Globalization (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Globalization.Calendars (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Globalization (>= 4.3) + System.Runtime (>= 4.3) + System.Globalization.Extensions (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + System.Globalization (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.IO (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.IO.FileSystem (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.IO (>= 4.3) + System.IO.FileSystem.Primitives (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.IO.FileSystem.Primitives (4.3) + System.Runtime (>= 4.3) + System.Linq (4.3) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Memory (4.5.5) + System.Net.Http (4.3.4) + Microsoft.NETCore.Platforms (>= 1.1.1) + runtime.native.System (>= 4.3) + runtime.native.System.Net.Http (>= 4.3) + runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.Diagnostics.DiagnosticSource (>= 4.3) + System.Diagnostics.Tracing (>= 4.3) + System.Globalization (>= 4.3) + System.Globalization.Extensions (>= 4.3) + System.IO (>= 4.3) + System.IO.FileSystem (>= 4.3) + System.Net.Primitives (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Security.Cryptography.Algorithms (>= 4.3) + System.Security.Cryptography.Encoding (>= 4.3) + System.Security.Cryptography.OpenSsl (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Security.Cryptography.X509Certificates (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.Net.Http.WinHttpHandler (8.0.1) + System.Net.Primitives (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + System.Runtime (>= 4.3.1) + System.Runtime.Handles (>= 4.3) + System.Reactive (5.0) + System.Reflection (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.IO (>= 4.3) + System.Reflection.Primitives (>= 4.3) + System.Runtime (>= 4.3) + System.Reflection.Metadata (8.0) + System.Collections.Immutable (>= 8.0) + System.Reflection.MetadataLoadContext (8.0) + System.Collections.Immutable (>= 8.0) + System.Reflection.Metadata (>= 8.0) + System.Reflection.Primitives (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Resources.Extensions (8.0) + System.Resources.ResourceManager (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Globalization (>= 4.3) + System.Reflection (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + System.Runtime.CompilerServices.Unsafe (6.0) + System.Runtime.Extensions (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + System.Runtime (>= 4.3.1) + System.Runtime.Handles (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Runtime.InteropServices (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Reflection (>= 4.3) + System.Reflection.Primitives (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.Numerics (4.3) + System.Globalization (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Security.AccessControl (6.0.1) + System.Security.Cryptography.Algorithms (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1) + runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) + runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) + System.Collections (>= 4.3) + System.IO (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Runtime.Numerics (>= 4.3) + System.Security.Cryptography.Encoding (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Security.Cryptography.Cng (5.0) + System.Formats.Asn1 (>= 5.0) + System.Security.Cryptography.Csp (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + System.IO (>= 4.3) + System.Reflection (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Security.Cryptography.Algorithms (>= 4.3) + System.Security.Cryptography.Encoding (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading (>= 4.3) + System.Security.Cryptography.Encoding (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3) + System.Collections (>= 4.3) + System.Collections.Concurrent (>= 4.3) + System.Linq (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Security.Cryptography.OpenSsl (5.0) + System.Formats.Asn1 (>= 5.0) + System.Security.Cryptography.Pkcs (8.0) + System.Formats.Asn1 (>= 8.0) + System.Security.Cryptography.Primitives (4.3) + System.Diagnostics.Debug (>= 4.3) + System.Globalization (>= 4.3) + System.IO (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Threading (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.Security.Cryptography.ProtectedData (8.0) + System.Security.Cryptography.X509Certificates (4.3.2) + Microsoft.NETCore.Platforms (>= 1.1) + runtime.native.System (>= 4.3) + runtime.native.System.Net.Http (>= 4.3) + runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.Globalization (>= 4.3) + System.Globalization.Calendars (>= 4.3) + System.IO (>= 4.3) + System.IO.FileSystem (>= 4.3) + System.IO.FileSystem.Primitives (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Runtime.Numerics (>= 4.3) + System.Security.Cryptography.Algorithms (>= 4.3) + System.Security.Cryptography.Cng (>= 4.3) + System.Security.Cryptography.Csp (>= 4.3) + System.Security.Cryptography.Encoding (>= 4.3) + System.Security.Cryptography.OpenSsl (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading (>= 4.3) + System.Security.Cryptography.Xml (8.0.1) + System.Security.Cryptography.Pkcs (>= 8.0) + System.Security.Permissions (8.0) + System.Windows.Extensions (>= 8.0) + System.Security.Principal.Windows (5.0) + System.Text.Encoding (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Text.Encoding.CodePages (8.0) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Text.Encodings.Web (8.0) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Text.Json (8.0.4) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Text.Encodings.Web (>= 8.0) + System.Threading (4.3) + System.Runtime (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.Threading.Tasks (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Threading.Tasks.Dataflow (8.0.1) + System.Windows.Extensions (8.0) + +GROUP Myriad +STORAGE: NONE +RESTRICTION: == net6.0 +NUGET + remote: https://api.nuget.org/v3/index.json + Chessie (0.6) + FSharp.Core (>= 4.0.1.7-alpha) + NETStandard.Library (>= 1.6) + Fantomas (6.3.10) + FSharp.Core (6.0.3) + FSharp.Data (6.4) + FSharp.Core (>= 6.0.1) + FSharp.Data.Csv.Core (>= 6.4) + FSharp.Data.Html.Core (>= 6.4) + FSharp.Data.Http (>= 6.4) + FSharp.Data.Json.Core (>= 6.4) + FSharp.Data.Runtime.Utilities (>= 6.4) + FSharp.Data.WorldBank.Core (>= 6.4) + FSharp.Data.Xml.Core (>= 6.4) + FSharp.Data.Csv.Core (6.4) + FSharp.Core (>= 6.0.1) + FSharp.Data.Runtime.Utilities (>= 6.4) + FSharp.Data.Html.Core (6.4) + FSharp.Core (>= 6.0.1) + FSharp.Data.Csv.Core (>= 6.4) + FSharp.Data.Runtime.Utilities (>= 6.4) + FSharp.Data.Http (6.4) + FSharp.Core (>= 6.0.1) + FSharp.Data.Json.Core (6.4) + FSharp.Core (>= 6.0.1) + FSharp.Data.Http (>= 6.4) + FSharp.Data.Runtime.Utilities (>= 6.4) + FSharp.Data.Runtime.Utilities (6.4) + FSharp.Core (>= 6.0.1) + FSharp.Data.Http (>= 6.4) + FSharp.Data.WorldBank.Core (6.4) + FSharp.Core (>= 6.0.1) + FSharp.Data.Http (>= 6.4) + FSharp.Data.Json.Core (>= 6.4) + FSharp.Data.Runtime.Utilities (>= 6.4) + FSharp.Data.Xml.Core (6.4) + FSharp.Core (>= 6.0.1) + FSharp.Data.Http (>= 6.4) + FSharp.Data.Json.Core (>= 6.4) + FSharp.Data.Runtime.Utilities (>= 6.4) + FSharp.Text.RegexProvider (2.1) + FSharp.Core (>= 4.3.4) + Microsoft.NETCore.Platforms (7.0.4) + Microsoft.NETCore.Targets (5.0) + Mono.Cecil (0.11.5) + Myriad.Core (0.8.1) + Fantomas (>= 4.7.9) + Myriad.Sdk (0.8.1) + NETStandard.Library (2.0.3) + Microsoft.NETCore.Platforms (>= 1.1) + Newtonsoft.Json (13.0.3) + NuGet.Common (6.10.1) + NuGet.Frameworks (>= 6.10.1) + NuGet.Configuration (6.10.1) + NuGet.Common (>= 6.10.1) + System.Security.Cryptography.ProtectedData (>= 4.4) + NuGet.Frameworks (6.10.1) + NuGet.Packaging (6.10.1) + Newtonsoft.Json (>= 13.0.3) + NuGet.Configuration (>= 6.10.1) + NuGet.Versioning (>= 6.10.1) + System.Security.Cryptography.Pkcs (>= 6.0.4) + NuGet.Versioning (6.10.1) + Paket.Core (8.0.3) + Chessie (>= 0.6) + FSharp.Core (6.0.3) + Mono.Cecil (>= 0.11.3 < 0.12) + Newtonsoft.Json (>= 13.0.1) + NuGet.Packaging (>= 5.9.1) + System.Net.Http (>= 4.3.4) + System.Net.Http.WinHttpHandler (>= 5.0) + System.Security.Cryptography.ProtectedData (>= 5.0) + runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.native.System (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + runtime.native.System.Net.Http (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + runtime.native.System.Security.Cryptography.Apple (4.3.1) + runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) + runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.debian.9-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.fedora.27-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.fedora.28-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.3) + runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.opensuse.42.3-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple (4.3.1) + runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + runtime.ubuntu.18.04-x64.runtime.native.System.Security.Cryptography.OpenSsl (4.3.3) + System.Collections (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Collections.Concurrent (4.3) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.Diagnostics.Tracing (>= 4.3) + System.Globalization (>= 4.3) + System.Reflection (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Threading (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.Diagnostics.Debug (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Diagnostics.DiagnosticSource (8.0.1) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + System.Diagnostics.Tracing (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Formats.Asn1 (8.0.1) + System.Globalization (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Globalization.Calendars (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Globalization (>= 4.3) + System.Runtime (>= 4.3) + System.Globalization.Extensions (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + System.Globalization (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.IO (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.IO.FileSystem (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.IO (>= 4.3) + System.IO.FileSystem.Primitives (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.IO.FileSystem.Primitives (4.3) + System.Runtime (>= 4.3) + System.Linq (4.3) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Net.Http (4.3.4) + Microsoft.NETCore.Platforms (>= 1.1.1) + runtime.native.System (>= 4.3) + runtime.native.System.Net.Http (>= 4.3) + runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.Diagnostics.DiagnosticSource (>= 4.3) + System.Diagnostics.Tracing (>= 4.3) + System.Globalization (>= 4.3) + System.Globalization.Extensions (>= 4.3) + System.IO (>= 4.3) + System.IO.FileSystem (>= 4.3) + System.Net.Primitives (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Security.Cryptography.Algorithms (>= 4.3) + System.Security.Cryptography.Encoding (>= 4.3) + System.Security.Cryptography.OpenSsl (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Security.Cryptography.X509Certificates (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.Net.Http.WinHttpHandler (8.0.1) + System.Net.Primitives (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + System.Runtime (>= 4.3.1) + System.Runtime.Handles (>= 4.3) + System.Reflection (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.IO (>= 4.3) + System.Reflection.Primitives (>= 4.3) + System.Runtime (>= 4.3) + System.Reflection.Primitives (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Resources.ResourceManager (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Globalization (>= 4.3) + System.Reflection (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + System.Runtime.CompilerServices.Unsafe (6.0) + System.Runtime.Extensions (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1.1) + Microsoft.NETCore.Targets (>= 1.1.3) + System.Runtime (>= 4.3.1) + System.Runtime.Handles (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Runtime.InteropServices (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Reflection (>= 4.3) + System.Reflection.Primitives (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.Numerics (4.3) + System.Globalization (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Security.Cryptography.Algorithms (4.3.1) + Microsoft.NETCore.Platforms (>= 1.1) + runtime.native.System.Security.Cryptography.Apple (>= 4.3.1) + runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) + System.Collections (>= 4.3) + System.IO (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Runtime.Numerics (>= 4.3) + System.Security.Cryptography.Encoding (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Security.Cryptography.Cng (5.0) + System.Formats.Asn1 (>= 5.0) + System.Security.Cryptography.Csp (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + System.IO (>= 4.3) + System.Reflection (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Security.Cryptography.Algorithms (>= 4.3) + System.Security.Cryptography.Encoding (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading (>= 4.3) + System.Security.Cryptography.Encoding (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3) + System.Collections (>= 4.3) + System.Collections.Concurrent (>= 4.3) + System.Linq (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Security.Cryptography.OpenSsl (5.0) + System.Formats.Asn1 (>= 5.0) + System.Security.Cryptography.Pkcs (8.0) + System.Formats.Asn1 (>= 8.0) + System.Security.Cryptography.Primitives (4.3) + System.Diagnostics.Debug (>= 4.3) + System.Globalization (>= 4.3) + System.IO (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Threading (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.Security.Cryptography.ProtectedData (8.0) + System.Security.Cryptography.X509Certificates (4.3.2) + Microsoft.NETCore.Platforms (>= 1.1) + runtime.native.System (>= 4.3) + runtime.native.System.Net.Http (>= 4.3) + runtime.native.System.Security.Cryptography.OpenSsl (>= 4.3.2) + System.Collections (>= 4.3) + System.Diagnostics.Debug (>= 4.3) + System.Globalization (>= 4.3) + System.Globalization.Calendars (>= 4.3) + System.IO (>= 4.3) + System.IO.FileSystem (>= 4.3) + System.IO.FileSystem.Primitives (>= 4.3) + System.Resources.ResourceManager (>= 4.3) + System.Runtime (>= 4.3) + System.Runtime.Extensions (>= 4.3) + System.Runtime.Handles (>= 4.3) + System.Runtime.InteropServices (>= 4.3) + System.Runtime.Numerics (>= 4.3) + System.Security.Cryptography.Algorithms (>= 4.3) + System.Security.Cryptography.Cng (>= 4.3) + System.Security.Cryptography.Csp (>= 4.3) + System.Security.Cryptography.Encoding (>= 4.3) + System.Security.Cryptography.OpenSsl (>= 4.3) + System.Security.Cryptography.Primitives (>= 4.3) + System.Text.Encoding (>= 4.3) + System.Threading (>= 4.3) + System.Text.Encoding (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + System.Threading (4.3) + System.Runtime (>= 4.3) + System.Threading.Tasks (>= 4.3) + System.Threading.Tasks (4.3) + Microsoft.NETCore.Platforms (>= 1.1) + Microsoft.NETCore.Targets (>= 1.1) + System.Runtime (>= 4.3) + +GROUP Providers +STORAGE: NONE +RESTRICTION: == net8.0 +NUGET + remote: https://api.nuget.org/v3/index.json + Ben.Demystifier (0.4.1) + System.Reflection.Metadata (>= 5.0) + FSharp.Core (9.0.100) + Glob (1.1.9) + Google.Protobuf (3.29.2) + Grpc.AspNetCore.Server (2.67) + Grpc.Net.Common (>= 2.67) + Grpc.AspNetCore.Server.Reflection (2.67) + Google.Protobuf (>= 3.27) + Grpc.AspNetCore.Server (>= 2.67) + Grpc.Reflection (>= 2.67) + Grpc.Core.Api (2.67) + Grpc.Net.Client (2.67) + Grpc.Net.Common (>= 2.67) + Microsoft.Extensions.Logging.Abstractions (>= 6.0) + Grpc.Net.Common (2.67) + Grpc.Core.Api (>= 2.67) + Grpc.Reflection (2.67) + Google.Protobuf (>= 3.27) + Grpc.Core.Api (>= 2.67) + Microsoft.Extensions.DependencyInjection (9.0) + Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0) + Microsoft.Extensions.DependencyInjection.Abstractions (9.0) + Microsoft.Extensions.Logging (9.0) + Microsoft.Extensions.DependencyInjection (>= 9.0) + Microsoft.Extensions.Logging.Abstractions (>= 9.0) + Microsoft.Extensions.Options (>= 9.0) + Microsoft.Extensions.Logging.Abstractions (9.0) + Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0) + System.Diagnostics.DiagnosticSource (>= 9.0) + Microsoft.Extensions.Options (9.0) + Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0) + Microsoft.Extensions.Primitives (>= 9.0) + Microsoft.Extensions.Primitives (9.0) + OneOf (3.0.271) + Pulumi (3.71) + Ben.Demystifier (>= 0.4.1) + Grpc.AspNetCore.Server (>= 2.63) + Grpc.AspNetCore.Server.Reflection (>= 2.63) + Grpc.Net.Client (>= 2.63) + Microsoft.Extensions.Logging.Abstractions (>= 6.0) + OneOf (>= 3.0.216) + Pulumi.Protobuf (>= 3.27.3) + Semver (>= 2.1) + Serilog.Extensions.Logging (>= 3.0.1) + Serilog.Sinks.Console (>= 4.0.1) + Pulumi.Auth0 (3.10.2) + Pulumi (>= 3.71) + Pulumi.Aws (6.65) + Pulumi (>= 3.71) + Pulumi.Azure (6.14) + Pulumi (>= 3.71) + Pulumi.AzureAD (6.0.2) + Pulumi (>= 3.71) + Pulumi.AzureNative (2.78) + Pulumi (>= 3.71) + System.Collections.Immutable (>= 5.0) + Pulumi.Command (1.0.1) + Pulumi (>= 3.65) + Pulumi.DigitalOcean (4.37.1) + Pulumi (>= 3.71) + Pulumi.Docker (4.5.8) + Pulumi (>= 3.71) + Pulumi.FSharp (3.71) + FSharp.Core (>= 4.7.2) + Pulumi (>= 3.71) + Pulumi.FSharp.Core (3.1.5) + FSharp.Core (>= 6.0.6) + Pulumi.FSharp (>= 3.43.1) + Pulumi.Gcp (8.12) + Pulumi (>= 3.71) + Pulumi.Kubernetes (4.19) + Glob (>= 1.1.5) + Pulumi (>= 3.71) + Pulumi.Protobuf (3.27.3) + Pulumi.Random (4.16.8) + Pulumi (>= 3.71) + Pulumi.Tls (5.0.10) + Pulumi (>= 3.71) + Semver (3.0) + Microsoft.Extensions.Primitives (>= 5.0.1) + Serilog (4.2) + Serilog.Extensions.Logging (9.0) + Microsoft.Extensions.Logging (>= 9.0) + Serilog (>= 4.2) + Serilog.Sinks.Console (6.0) + Serilog (>= 4.0) + System.Collections.Immutable (9.0) + System.Diagnostics.DiagnosticSource (9.0) + System.Reflection.Metadata (9.0) + System.Collections.Immutable (>= 9.0) diff --git a/Pulumi.FSharp.Docker/.gitignore b/providers/Pulumi.FSharp.Auth0/.gitignore similarity index 99% rename from Pulumi.FSharp.Docker/.gitignore rename to providers/Pulumi.FSharp.Auth0/.gitignore index 58f4e8c..7a84deb 100644 --- a/Pulumi.FSharp.Docker/.gitignore +++ b/providers/Pulumi.FSharp.Auth0/.gitignore @@ -351,6 +351,6 @@ MigrationBackup/ .idea/ -/azure-native.*.json +/auth0.*.json /Generated.fs /Generated.*.fs \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Auth0/Myriad.fs b/providers/Pulumi.FSharp.Auth0/Myriad.fs new file mode 100644 index 0000000..0b0606e --- /dev/null +++ b/providers/Pulumi.FSharp.Auth0/Myriad.fs @@ -0,0 +1,3 @@ +module private Auth0 + +module Force = let private nonce = 669580010 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Auth0/Pulumi.FSharp.Auth0.fsproj b/providers/Pulumi.FSharp.Auth0/Pulumi.FSharp.Auth0.fsproj new file mode 100644 index 0000000..ae3fda2 --- /dev/null +++ b/providers/Pulumi.FSharp.Auth0/Pulumi.FSharp.Auth0.fsproj @@ -0,0 +1,35 @@ + + + + net8.0 + $(MSBuildProjectName) + NU1605,NU1608,FS0058,FS0044 + true + fsharp pulumi auth0 identity oidc oauth + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Aws/myriad.toml b/providers/Pulumi.FSharp.Auth0/myriad.toml similarity index 100% rename from Pulumi.FSharp.Aws/myriad.toml rename to providers/Pulumi.FSharp.Auth0/myriad.toml diff --git a/providers/Pulumi.FSharp.Auth0/paket.references b/providers/Pulumi.FSharp.Auth0/paket.references new file mode 100644 index 0000000..2e3e74d --- /dev/null +++ b/providers/Pulumi.FSharp.Auth0/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.Auth0 + Pulumi.FSharp \ No newline at end of file diff --git a/Pulumi.FSharp.Aws/.gitignore b/providers/Pulumi.FSharp.Aws/.gitignore similarity index 100% rename from Pulumi.FSharp.Aws/.gitignore rename to providers/Pulumi.FSharp.Aws/.gitignore diff --git a/providers/Pulumi.FSharp.Aws/Myriad.fs b/providers/Pulumi.FSharp.Aws/Myriad.fs new file mode 100644 index 0000000..c487934 --- /dev/null +++ b/providers/Pulumi.FSharp.Aws/Myriad.fs @@ -0,0 +1,3 @@ +module private Aws + +module Force = let private nonce = 1256465707 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Aws/Pulumi.FSharp.Aws.fsproj b/providers/Pulumi.FSharp.Aws/Pulumi.FSharp.Aws.fsproj new file mode 100644 index 0000000..ea5b954 --- /dev/null +++ b/providers/Pulumi.FSharp.Aws/Pulumi.FSharp.Aws.fsproj @@ -0,0 +1,34 @@ + + + + net8.0 + fsharp pulumi aws + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Azure/myriad.toml b/providers/Pulumi.FSharp.Aws/myriad.toml similarity index 100% rename from Pulumi.FSharp.Azure/myriad.toml rename to providers/Pulumi.FSharp.Aws/myriad.toml diff --git a/providers/Pulumi.FSharp.Aws/paket.references b/providers/Pulumi.FSharp.Aws/paket.references new file mode 100644 index 0000000..451d877 --- /dev/null +++ b/providers/Pulumi.FSharp.Aws/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.Aws + Pulumi.FSharp \ No newline at end of file diff --git a/Pulumi.FSharp.Azure/.gitignore b/providers/Pulumi.FSharp.Azure/.gitignore similarity index 100% rename from Pulumi.FSharp.Azure/.gitignore rename to providers/Pulumi.FSharp.Azure/.gitignore diff --git a/providers/Pulumi.FSharp.Azure/Myriad.fs b/providers/Pulumi.FSharp.Azure/Myriad.fs new file mode 100644 index 0000000..20eaf73 --- /dev/null +++ b/providers/Pulumi.FSharp.Azure/Myriad.fs @@ -0,0 +1,3 @@ +module private Azure + +module Force = let private nonce = 446685478 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Azure/Pulumi.FSharp.Azure.fsproj b/providers/Pulumi.FSharp.Azure/Pulumi.FSharp.Azure.fsproj new file mode 100644 index 0000000..8272d85 --- /dev/null +++ b/providers/Pulumi.FSharp.Azure/Pulumi.FSharp.Azure.fsproj @@ -0,0 +1,35 @@ + + + + net8.0 + fsharp pulumi azure + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Azure/Storage/SasToken.fs b/providers/Pulumi.FSharp.Azure/Storage/SasToken.fs similarity index 51% rename from Pulumi.FSharp.Azure/Storage/SasToken.fs rename to providers/Pulumi.FSharp.Azure/Storage/SasToken.fs index 7f1ca44..fb41704 100644 --- a/Pulumi.FSharp.Azure/Storage/SasToken.fs +++ b/providers/Pulumi.FSharp.Azure/Storage/SasToken.fs @@ -5,10 +5,7 @@ open Pulumi.FSharp.Outputs open Pulumi.Azure.Storage open System -type TimeRange = { - From: DateTime - To: DateTime -} +type TimeRange = { From: DateTime; To: DateTime } type Permission = | Add @@ -18,7 +15,7 @@ type Permission = | Create | Delete -module SasTokenInternal = +module SasTokenInternal = type StorageBlobArgsRecord = { StorageAccount: Account StorageContainer: Container @@ -30,33 +27,31 @@ module SasTokenInternal = open SasTokenInternal type SasTokenBuilder internal () = - + let granularSas args range permissions = output { - let! connectionString = - args.StorageAccount.PrimaryConnectionString - - let! containerName = - args.StorageContainer.Name - - let! result = + let! connectionString = args.StorageAccount.PrimaryConnectionString + + let! containerName = args.StorageContainer.Name + + let! result = GetAccountBlobContainerSASArgs( ConnectionString = connectionString, ContainerName = containerName, Start = range.From.ToString("u").Replace(' ', 'T'), Expiry = range.To.ToString("u").Replace(' ', 'T'), Permissions = permissions - ) |> - GetAccountBlobContainerSAS.InvokeAsync - + ) + |> GetAccountBlobContainerSAS.InvokeAsync + return result.Sas } - + let toArgs permissions = let has permission = - permissions |> - List.contains permission - + permissions + |> List.contains permission + GetAccountBlobContainerSASPermissionsArgs( Add = (has Add), List = (has List), @@ -65,12 +60,12 @@ type SasTokenBuilder internal () = Create = (has Create), Delete = (has Delete) ) - + let defaultDuration = { From = DateTime.Now To = DateTime.Now.AddDays(1.) } - + member __.Yield _ = { StorageAccount = null StorageContainer = null @@ -78,42 +73,60 @@ type SasTokenBuilder internal () = TimeRange = None Permissions = [] } - - member __.Run (args) = - let token = + + member __.Run(args) = + let token = match args.TimeRange, args.Permissions with | None, [] - | None, [ Read ] -> SharedAccessSignature.SignedBlobReadUrl(args.Blob, - args.StorageAccount) - | Some range, perms -> granularSas args range (perms |> toArgs) - | None, perms -> granularSas args defaultDuration (perms |> toArgs) - - secretOutput { - return! token - } - + | None, [ Read ] -> + SharedAccessSignature.SignedBlobReadUrl(args.Blob, args.StorageAccount) + | Some range, perms -> + granularSas + args + range + (perms + |> toArgs) + | None, perms -> + granularSas + args + defaultDuration + (perms + |> toArgs) + + secretOutput { return! token } + [] - member __.Blob(args, blob) = - { args with Blob = blob } + member __.Blob(args, blob) = { args with Blob = blob } [] - member __.Account(args, storageAccount) = - { args with StorageAccount = storageAccount } - + member __.Account(args, storageAccount) = { + args with + StorageAccount = storageAccount + } + [] - member __.Container(args, storageContainer) = - { args with StorageContainer = storageContainer } + member __.Container(args, storageContainer) = { + args with + StorageContainer = storageContainer + } [] - member __.Duration(args, range) = - { args with TimeRange = Some range } - + member __.Duration(args, range) = { args with TimeRange = Some range } + [] - member __.Permission(args, permission) = - { args with Permissions = permission :: args.Permissions } - + member __.Permission(args, permission) = { + args with + Permissions = + permission + :: args.Permissions + } + [] - member __.Permissions(args, permissions) = - { args with Permissions = args.Permissions @ permissions } + member __.Permissions(args, permissions) = { + args with + Permissions = + args.Permissions + @ permissions + } -let sasToken = SasTokenBuilder() \ No newline at end of file +let sasToken = SasTokenBuilder() diff --git a/Pulumi.FSharp.AzureAD/myriad.toml b/providers/Pulumi.FSharp.Azure/myriad.toml similarity index 100% rename from Pulumi.FSharp.AzureAD/myriad.toml rename to providers/Pulumi.FSharp.Azure/myriad.toml diff --git a/providers/Pulumi.FSharp.Azure/paket.references b/providers/Pulumi.FSharp.Azure/paket.references new file mode 100644 index 0000000..ed8e255 --- /dev/null +++ b/providers/Pulumi.FSharp.Azure/paket.references @@ -0,0 +1,6 @@ +Myriad.Sdk + +group Providers + Pulumi.Azure + Pulumi.FSharp + Pulumi.FSharp.Core \ No newline at end of file diff --git a/Pulumi.FSharp.AzureAD/.gitignore b/providers/Pulumi.FSharp.AzureAD/.gitignore similarity index 100% rename from Pulumi.FSharp.AzureAD/.gitignore rename to providers/Pulumi.FSharp.AzureAD/.gitignore diff --git a/providers/Pulumi.FSharp.AzureAD/Myriad.fs b/providers/Pulumi.FSharp.AzureAD/Myriad.fs new file mode 100644 index 0000000..1394bbc --- /dev/null +++ b/providers/Pulumi.FSharp.AzureAD/Myriad.fs @@ -0,0 +1,4 @@ +module private AzureAD + +module Force = + let private nonce = 1789749124 diff --git a/providers/Pulumi.FSharp.AzureAD/Pulumi.FSharp.AzureAD.fsproj b/providers/Pulumi.FSharp.AzureAD/Pulumi.FSharp.AzureAD.fsproj new file mode 100644 index 0000000..4fb1a0a --- /dev/null +++ b/providers/Pulumi.FSharp.AzureAD/Pulumi.FSharp.AzureAD.fsproj @@ -0,0 +1,39 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi azuread + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.AzureNative/myriad.toml b/providers/Pulumi.FSharp.AzureAD/myriad.toml similarity index 100% rename from Pulumi.FSharp.AzureNative/myriad.toml rename to providers/Pulumi.FSharp.AzureAD/myriad.toml diff --git a/providers/Pulumi.FSharp.AzureAD/paket.references b/providers/Pulumi.FSharp.AzureAD/paket.references new file mode 100644 index 0000000..fb13033 --- /dev/null +++ b/providers/Pulumi.FSharp.AzureAD/paket.references @@ -0,0 +1,6 @@ + +Myriad.Sdk + +group Providers + Pulumi.AzureAD + Pulumi.FSharp \ No newline at end of file diff --git a/Pulumi.FSharp.AzureNative/.gitignore b/providers/Pulumi.FSharp.AzureNative/.gitignore similarity index 100% rename from Pulumi.FSharp.AzureNative/.gitignore rename to providers/Pulumi.FSharp.AzureNative/.gitignore diff --git a/providers/Pulumi.FSharp.AzureNative/Myriad.fs b/providers/Pulumi.FSharp.AzureNative/Myriad.fs new file mode 100644 index 0000000..1b2354f --- /dev/null +++ b/providers/Pulumi.FSharp.AzureNative/Myriad.fs @@ -0,0 +1,3 @@ +module private Azure + +module Force = let private nonce = 1786119601 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.AzureNative/Pulumi.FSharp.AzureNative.fsproj b/providers/Pulumi.FSharp.AzureNative/Pulumi.FSharp.AzureNative.fsproj new file mode 100644 index 0000000..8a1a640 --- /dev/null +++ b/providers/Pulumi.FSharp.AzureNative/Pulumi.FSharp.AzureNative.fsproj @@ -0,0 +1,41 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi azure + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.AzureNativeV2/myriad.toml b/providers/Pulumi.FSharp.AzureNative/myriad.toml similarity index 100% rename from Pulumi.FSharp.AzureNativeV2/myriad.toml rename to providers/Pulumi.FSharp.AzureNative/myriad.toml diff --git a/providers/Pulumi.FSharp.AzureNative/paket.references b/providers/Pulumi.FSharp.AzureNative/paket.references new file mode 100644 index 0000000..fd41288 --- /dev/null +++ b/providers/Pulumi.FSharp.AzureNative/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.AzureNative + Pulumi.FSharp \ No newline at end of file diff --git a/Pulumi.FSharp.AzureNativeV2/.gitignore b/providers/Pulumi.FSharp.AzureNativeV2/.gitignore similarity index 100% rename from Pulumi.FSharp.AzureNativeV2/.gitignore rename to providers/Pulumi.FSharp.AzureNativeV2/.gitignore diff --git a/providers/Pulumi.FSharp.AzureNativeV2/Myriad.fs b/providers/Pulumi.FSharp.AzureNativeV2/Myriad.fs new file mode 100644 index 0000000..3d36ed3 --- /dev/null +++ b/providers/Pulumi.FSharp.AzureNativeV2/Myriad.fs @@ -0,0 +1,3 @@ +module private AzureNativeV2 + +module Force = let private nonce = 23899918 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.AzureNativeV2/Pulumi.FSharp.AzureNativeV2.fsproj b/providers/Pulumi.FSharp.AzureNativeV2/Pulumi.FSharp.AzureNativeV2.fsproj new file mode 100644 index 0000000..f1062d2 --- /dev/null +++ b/providers/Pulumi.FSharp.AzureNativeV2/Pulumi.FSharp.AzureNativeV2.fsproj @@ -0,0 +1,41 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi azure + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Command/myriad.toml b/providers/Pulumi.FSharp.AzureNativeV2/myriad.toml similarity index 100% rename from Pulumi.FSharp.Command/myriad.toml rename to providers/Pulumi.FSharp.AzureNativeV2/myriad.toml diff --git a/providers/Pulumi.FSharp.AzureNativeV2/paket.references b/providers/Pulumi.FSharp.AzureNativeV2/paket.references new file mode 100644 index 0000000..fd41288 --- /dev/null +++ b/providers/Pulumi.FSharp.AzureNativeV2/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.AzureNative + Pulumi.FSharp \ No newline at end of file diff --git a/Pulumi.FSharp.Command/.gitignore b/providers/Pulumi.FSharp.Command/.gitignore similarity index 100% rename from Pulumi.FSharp.Command/.gitignore rename to providers/Pulumi.FSharp.Command/.gitignore diff --git a/providers/Pulumi.FSharp.Command/Myriad.fs b/providers/Pulumi.FSharp.Command/Myriad.fs new file mode 100644 index 0000000..ff78f2f --- /dev/null +++ b/providers/Pulumi.FSharp.Command/Myriad.fs @@ -0,0 +1,3 @@ +module private Command + +module Force = let private nonce = 1320620330 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Command/Pulumi.FSharp.Command.fsproj b/providers/Pulumi.FSharp.Command/Pulumi.FSharp.Command.fsproj new file mode 100644 index 0000000..3e66310 --- /dev/null +++ b/providers/Pulumi.FSharp.Command/Pulumi.FSharp.Command.fsproj @@ -0,0 +1,39 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi command + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Docker/myriad.toml b/providers/Pulumi.FSharp.Command/myriad.toml similarity index 100% rename from Pulumi.FSharp.Docker/myriad.toml rename to providers/Pulumi.FSharp.Command/myriad.toml diff --git a/providers/Pulumi.FSharp.Command/paket.references b/providers/Pulumi.FSharp.Command/paket.references new file mode 100644 index 0000000..e7525b6 --- /dev/null +++ b/providers/Pulumi.FSharp.Command/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.Command + Pulumi.FSharp \ No newline at end of file diff --git a/Pulumi.FSharp.NuGet.Test/.gitignore b/providers/Pulumi.FSharp.DigitalOcean/.gitignore similarity index 98% rename from Pulumi.FSharp.NuGet.Test/.gitignore rename to providers/Pulumi.FSharp.DigitalOcean/.gitignore index 663f9df..1f1a8aa 100644 --- a/Pulumi.FSharp.NuGet.Test/.gitignore +++ b/providers/Pulumi.FSharp.DigitalOcean/.gitignore @@ -127,9 +127,6 @@ _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user -# JustCode is a .NET coding add-in -.JustCode - # TeamCity is a build add-in _TeamCity* @@ -350,4 +347,10 @@ healthchecksdb MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder -.ionide/ \ No newline at end of file +.ionide/ + +.idea/ + +/digitalocean.*.json +/Generated.fs +/Generated.*.fs \ No newline at end of file diff --git a/providers/Pulumi.FSharp.DigitalOcean/Myriad.fs b/providers/Pulumi.FSharp.DigitalOcean/Myriad.fs new file mode 100644 index 0000000..dc0b007 --- /dev/null +++ b/providers/Pulumi.FSharp.DigitalOcean/Myriad.fs @@ -0,0 +1,3 @@ +module private DigitalOcean + +module Force = let private nonce = 229151174 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.DigitalOcean/Pulumi.FSharp.DigitalOcean.fsproj b/providers/Pulumi.FSharp.DigitalOcean/Pulumi.FSharp.DigitalOcean.fsproj new file mode 100644 index 0000000..da03d58 --- /dev/null +++ b/providers/Pulumi.FSharp.DigitalOcean/Pulumi.FSharp.DigitalOcean.fsproj @@ -0,0 +1,39 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi digitalocean + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Gcp/myriad.toml b/providers/Pulumi.FSharp.DigitalOcean/myriad.toml similarity index 100% rename from Pulumi.FSharp.Gcp/myriad.toml rename to providers/Pulumi.FSharp.DigitalOcean/myriad.toml diff --git a/providers/Pulumi.FSharp.DigitalOcean/paket.references b/providers/Pulumi.FSharp.DigitalOcean/paket.references new file mode 100644 index 0000000..da3b042 --- /dev/null +++ b/providers/Pulumi.FSharp.DigitalOcean/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.DigitalOcean + Pulumi.FSharp \ No newline at end of file diff --git a/Pulumi.FSharp.Test/.gitignore b/providers/Pulumi.FSharp.Docker/.gitignore similarity index 99% rename from Pulumi.FSharp.Test/.gitignore rename to providers/Pulumi.FSharp.Docker/.gitignore index e645270..06ca7a4 100644 --- a/Pulumi.FSharp.Test/.gitignore +++ b/providers/Pulumi.FSharp.Docker/.gitignore @@ -127,9 +127,6 @@ _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user -# JustCode is a .NET coding add-in -.JustCode - # TeamCity is a build add-in _TeamCity* @@ -351,3 +348,9 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ + +.idea/ + +/docker.*.json +/Generated.fs +/Generated.*.fs \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Docker/Myriad.fs b/providers/Pulumi.FSharp.Docker/Myriad.fs new file mode 100644 index 0000000..5774a7e --- /dev/null +++ b/providers/Pulumi.FSharp.Docker/Myriad.fs @@ -0,0 +1,3 @@ +module private Docker + +module Force = let private nonce = 309386481 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Docker/Pulumi.FSharp.Docker.fsproj b/providers/Pulumi.FSharp.Docker/Pulumi.FSharp.Docker.fsproj new file mode 100644 index 0000000..a895bbf --- /dev/null +++ b/providers/Pulumi.FSharp.Docker/Pulumi.FSharp.Docker.fsproj @@ -0,0 +1,39 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi docker + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Kubernetes/myriad.toml b/providers/Pulumi.FSharp.Docker/myriad.toml similarity index 100% rename from Pulumi.FSharp.Kubernetes/myriad.toml rename to providers/Pulumi.FSharp.Docker/myriad.toml diff --git a/providers/Pulumi.FSharp.Docker/paket.references b/providers/Pulumi.FSharp.Docker/paket.references new file mode 100644 index 0000000..0231308 --- /dev/null +++ b/providers/Pulumi.FSharp.Docker/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.Docker + Pulumi.FSharp \ No newline at end of file diff --git a/Pulumi.FSharp.Gcp/.gitignore b/providers/Pulumi.FSharp.Gcp/.gitignore similarity index 100% rename from Pulumi.FSharp.Gcp/.gitignore rename to providers/Pulumi.FSharp.Gcp/.gitignore diff --git a/providers/Pulumi.FSharp.Gcp/Myriad.fs b/providers/Pulumi.FSharp.Gcp/Myriad.fs new file mode 100644 index 0000000..f0734df --- /dev/null +++ b/providers/Pulumi.FSharp.Gcp/Myriad.fs @@ -0,0 +1,3 @@ +module private Gcp + +module Force = let private nonce = 1108446254 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Gcp/Pulumi.FSharp.Gcp.fsproj b/providers/Pulumi.FSharp.Gcp/Pulumi.FSharp.Gcp.fsproj new file mode 100644 index 0000000..75fd1aa --- /dev/null +++ b/providers/Pulumi.FSharp.Gcp/Pulumi.FSharp.Gcp.fsproj @@ -0,0 +1,39 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi gcp + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Myriad/myriad.toml b/providers/Pulumi.FSharp.Gcp/myriad.toml similarity index 100% rename from Pulumi.FSharp.Myriad/myriad.toml rename to providers/Pulumi.FSharp.Gcp/myriad.toml diff --git a/providers/Pulumi.FSharp.Gcp/paket.references b/providers/Pulumi.FSharp.Gcp/paket.references new file mode 100644 index 0000000..c0bcc8c --- /dev/null +++ b/providers/Pulumi.FSharp.Gcp/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.FSharp + Pulumi.Gcp \ No newline at end of file diff --git a/Pulumi.FSharp.Kubernetes/.gitignore b/providers/Pulumi.FSharp.Kubernetes/.gitignore similarity index 100% rename from Pulumi.FSharp.Kubernetes/.gitignore rename to providers/Pulumi.FSharp.Kubernetes/.gitignore diff --git a/providers/Pulumi.FSharp.Kubernetes/Myriad.fs b/providers/Pulumi.FSharp.Kubernetes/Myriad.fs new file mode 100644 index 0000000..4f2b160 --- /dev/null +++ b/providers/Pulumi.FSharp.Kubernetes/Myriad.fs @@ -0,0 +1,4 @@ +module private Kubernetes + +module Force = + let private nonce = 1167240649 diff --git a/providers/Pulumi.FSharp.Kubernetes/Pulumi.FSharp.Kubernetes.fsproj b/providers/Pulumi.FSharp.Kubernetes/Pulumi.FSharp.Kubernetes.fsproj new file mode 100644 index 0000000..a56dedf --- /dev/null +++ b/providers/Pulumi.FSharp.Kubernetes/Pulumi.FSharp.Kubernetes.fsproj @@ -0,0 +1,34 @@ + + + + net8.0 + fsharp pulumi kubernetes + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Random/myriad.toml b/providers/Pulumi.FSharp.Kubernetes/myriad.toml similarity index 100% rename from Pulumi.FSharp.Random/myriad.toml rename to providers/Pulumi.FSharp.Kubernetes/myriad.toml diff --git a/providers/Pulumi.FSharp.Kubernetes/paket.references b/providers/Pulumi.FSharp.Kubernetes/paket.references new file mode 100644 index 0000000..c66bff6 --- /dev/null +++ b/providers/Pulumi.FSharp.Kubernetes/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.FSharp + Pulumi.Kubernetes diff --git a/Pulumi.FSharp.Random/.gitignore b/providers/Pulumi.FSharp.Random/.gitignore similarity index 100% rename from Pulumi.FSharp.Random/.gitignore rename to providers/Pulumi.FSharp.Random/.gitignore diff --git a/providers/Pulumi.FSharp.Random/Myriad.fs b/providers/Pulumi.FSharp.Random/Myriad.fs new file mode 100644 index 0000000..906a3a4 --- /dev/null +++ b/providers/Pulumi.FSharp.Random/Myriad.fs @@ -0,0 +1,3 @@ +module private Random + +module Force = let private nonce = 1761217279 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Random/Pulumi.FSharp.Random.fsproj b/providers/Pulumi.FSharp.Random/Pulumi.FSharp.Random.fsproj new file mode 100644 index 0000000..936aac9 --- /dev/null +++ b/providers/Pulumi.FSharp.Random/Pulumi.FSharp.Random.fsproj @@ -0,0 +1,39 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi random + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/Pulumi.FSharp.Tls/myriad.toml b/providers/Pulumi.FSharp.Random/myriad.toml similarity index 100% rename from Pulumi.FSharp.Tls/myriad.toml rename to providers/Pulumi.FSharp.Random/myriad.toml diff --git a/providers/Pulumi.FSharp.Random/paket.references b/providers/Pulumi.FSharp.Random/paket.references new file mode 100644 index 0000000..ee06147 --- /dev/null +++ b/providers/Pulumi.FSharp.Random/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.FSharp + Pulumi.Random diff --git a/Pulumi.FSharp.Tls/.gitignore b/providers/Pulumi.FSharp.Tls/.gitignore similarity index 100% rename from Pulumi.FSharp.Tls/.gitignore rename to providers/Pulumi.FSharp.Tls/.gitignore diff --git a/providers/Pulumi.FSharp.Tls/Myriad.fs b/providers/Pulumi.FSharp.Tls/Myriad.fs new file mode 100644 index 0000000..1ca7514 --- /dev/null +++ b/providers/Pulumi.FSharp.Tls/Myriad.fs @@ -0,0 +1,3 @@ +module private Tls + +module Force = let private nonce = 15078280 \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Tls/Pulumi.FSharp.Tls.fsproj b/providers/Pulumi.FSharp.Tls/Pulumi.FSharp.Tls.fsproj new file mode 100644 index 0000000..958d373 --- /dev/null +++ b/providers/Pulumi.FSharp.Tls/Pulumi.FSharp.Tls.fsproj @@ -0,0 +1,39 @@ + + + + net8.0 + F# computational expressions to reduce boilerplate in Pulumi code + Copyright 2021 + https://github.com/UnoSD/Pulumi.FSharp.Extensions + $(MSBuildProjectName) + https://github.com/UnoSD/Pulumi.FSharp.Extensions + fsharp pulumi tls + NU1605,NU1608,FS0058,FS0044 + true + + + + + + + + + + + + + + + + + + Myriad.fs + + + + + \ No newline at end of file diff --git a/providers/Pulumi.FSharp.Tls/myriad.toml b/providers/Pulumi.FSharp.Tls/myriad.toml new file mode 100644 index 0000000..e69de29 diff --git a/providers/Pulumi.FSharp.Tls/paket.references b/providers/Pulumi.FSharp.Tls/paket.references new file mode 100644 index 0000000..24e2d05 --- /dev/null +++ b/providers/Pulumi.FSharp.Tls/paket.references @@ -0,0 +1,5 @@ +Myriad.Sdk + +group Providers + Pulumi.FSharp + Pulumi.Tls diff --git a/Pulumi.FSharp.AzureNative.Common/Locations.fs b/src/Pulumi.FSharp.AzureNative.Common/Locations.fs similarity index 99% rename from Pulumi.FSharp.AzureNative.Common/Locations.fs rename to src/Pulumi.FSharp.AzureNative.Common/Locations.fs index e60d410..99f3eb5 100644 --- a/Pulumi.FSharp.AzureNative.Common/Locations.fs +++ b/src/Pulumi.FSharp.AzureNative.Common/Locations.fs @@ -224,4 +224,4 @@ let locationsMap = |> Map.add "(Middle East) UAE Central" "uaecentral" |> Map.add "brazilsoutheast" "brazilsoutheast" |> Map.add "Brazil Southeast" "brazilsoutheast" - |> Map.add "(South America) Brazil Southeast" "brazilsoutheast" \ No newline at end of file + |> Map.add "(South America) Brazil Southeast" "brazilsoutheast" diff --git a/src/Pulumi.FSharp.AzureNative.Common/NamingConventions.fs b/src/Pulumi.FSharp.AzureNative.Common/NamingConventions.fs new file mode 100644 index 0000000..b4e2422 --- /dev/null +++ b/src/Pulumi.FSharp.AzureNative.Common/NamingConventions.fs @@ -0,0 +1,46 @@ +module Pulumi.FSharp.NamingConventions.Azure + +open AzureLocations +open Pulumi + +// https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/resource-naming + +module Region = + let private shorten (regionName: string) = + regionName + .Replace("europe", "eu") + .Replace("brazil", "br") + .Replace("australia", "au") + .Replace("switzerland", "sw") + .Replace("pacific", "pac") + .Replace("unitedstates", "us") + .Replace("central", "c") + .Replace("north", "n") + .Replace("south", "s") + .Replace("east", "e") + .Replace("west", "w") + + let private configuredRegion = Config("azure-native").Get("location") + + let shortName = + locationsMap + |> Map.tryFind configuredRegion + |> Option.map (fun x -> + x + |> shorten + ) + |> Option.defaultWith (fun () -> + failwith $"Missing or incorrect azure-native:location: {configuredRegion}" + ) + +module Resource = + let private woa = + match Config().Get("workloadOrApplication") with + | null + | "" -> "" + | value -> $"{value}-" + + let name resourceType (instanceNumber: int) = + $"{resourceType}-{woa}{Deployment.Instance.StackName}-{Region.shortName}-{instanceNumber:D3}" + + let nameOne resourceType = name resourceType 1 diff --git a/src/Pulumi.FSharp.Core/Assets.fs b/src/Pulumi.FSharp.Core/Assets.fs new file mode 100644 index 0000000..5f537c1 --- /dev/null +++ b/src/Pulumi.FSharp.Core/Assets.fs @@ -0,0 +1,60 @@ +module Pulumi.FSharp.Assets + +open System.Collections.Generic +open Pulumi + +type FileArchive = { + ArchivePath: string +} with + + member this.ToPulumiType = FileArchive(this.ArchivePath) + +type RemoteArchive = { + ArchiveUri: string +} with + + member this.ToPulumiType = RemoteArchive(this.ArchiveUri) + +type RemoteAsset = { + Uri: string +} with + + member this.ToPulumiType = RemoteAsset(this.Uri) + +type FileAsset = { + Path: string +} with + + member this.ToPulumiType = FileAsset(this.Path) + +type StringAsset = { + Text: string +} with + + member this.ToPulumiType = StringAsset(this.Text) + +type Any = { Value: obj } + +type Asset = + | File of FileAsset + | FileArchive of FileArchive + | Remote of RemoteAsset + | RemoteArchive of RemoteArchive + | String of StringAsset + +type AssetArchive = { + Assets: Map +} with + + member this.ToPulumiType = + this.Assets + |> Map.map (fun _ a -> + match a with + | File f -> f.ToPulumiType :> AssetOrArchive + | FileArchive f -> f.ToPulumiType :> AssetOrArchive + | Remote f -> f.ToPulumiType :> AssetOrArchive + | RemoteArchive f -> f.ToPulumiType :> AssetOrArchive + | String f -> f.ToPulumiType :> AssetOrArchive + ) + |> Dictionary + |> AssetArchive diff --git a/src/Pulumi.FSharp.Core/CHANGELOG.md b/src/Pulumi.FSharp.Core/CHANGELOG.md new file mode 100644 index 0000000..34d6e63 --- /dev/null +++ b/src/Pulumi.FSharp.Core/CHANGELOG.md @@ -0,0 +1,31 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [3.1.7] - 2024-06-02 + + + +## [3.1.6] - 2024-05-31 + +Providers now use a dedicated FAKE dependency group to enable detection of updated providers via GitOps + +### Changed +- Provider dependencies moved from `Main` group to `Providers`. + +## [3.1.5] - 2024-05-31 + +Updated the project to use modern build tooling. + +### Fixed +- Numbers in provider names (e.g. `auth0`) no longer break the plugin. +- GCP resources that use slashes as namespacing (e.g. `gcp:privilegedaccessmanager/entitlement`) no longer break the plugin. + +### Added +- DigitalOcean provider +- Auth0 provider +- Support for Kubernetes `ConfigFile` and `ConfigGroup` types \ No newline at end of file diff --git a/src/Pulumi.FSharp.Core/Config.fs b/src/Pulumi.FSharp.Core/Config.fs new file mode 100644 index 0000000..4f803ac --- /dev/null +++ b/src/Pulumi.FSharp.Core/Config.fs @@ -0,0 +1,31 @@ +module Pulumi.FSharp.Config + +open Pulumi + +let private pulumiConfig = lazy Config() + +type Config() = + member _.Item + with get (name) = pulumiConfig.Value.Require(name) + + member _.get<'T>(key: string) = + pulumiConfig.Value.RequireObject<'T>(key) + + member _.tryGet<'T when 'T: null>(key: string) = + pulumiConfig.Value.GetObject<'T>(key) + |> Option.ofObj + +type SecretConfig() = + member _.Item + with get (name) = pulumiConfig.Value.RequireSecret(name) + + member _.get<'T>(key: string) = + pulumiConfig.Value.RequireSecretObject<'T>(key) + + member _.tryGet<'T>(key: string) = + pulumiConfig.Value.GetSecretObject<'T>(key) + |> Option.ofObj + +// Type provider for YAML config variables +let config = Config() +let secret = SecretConfig() diff --git a/Pulumi.FSharp.Core/CustomResourceOptions.fs b/src/Pulumi.FSharp.Core/CustomResourceOptions.fs similarity index 83% rename from Pulumi.FSharp.Core/CustomResourceOptions.fs rename to src/Pulumi.FSharp.Core/CustomResourceOptions.fs index 9a0cf5f..0f862eb 100644 --- a/Pulumi.FSharp.Core/CustomResourceOptions.fs +++ b/src/Pulumi.FSharp.Core/CustomResourceOptions.fs @@ -10,41 +10,53 @@ type CustomTimeoutsBuilder() = member _.Run(opts) = List.fold (fun opts f -> f opts) (CustomTimeouts()) opts - member this.Combine(lOpts, rOpts) = lOpts @ rOpts + member this.Combine(lOpts, rOpts) = + lOpts + @ rOpts + member this.For(opts, delayedOpts) = this.Combine(opts, delayedOpts ()) member _.Delay(f) = f () member _.Zero _ = () - + /// The optional create timeout. [] member _.Create(opts, value) = (fun (opts: CustomTimeouts) -> opts.Create <- Nullable value - opts) :: opts + opts + ) + :: opts /// The optional update timeout. [] member _.Update(opts, value) = (fun (opts: CustomTimeouts) -> opts.Update <- Nullable value - opts) :: opts + opts + ) + :: opts /// The optional delete timeout. [] member _.Delete(opts, value) = (fun (opts: CustomTimeouts) -> opts.Delete <- Nullable value - opts) :: opts + opts + ) + :: opts let customTimeouts = CustomTimeoutsBuilder() - + type CustomResourceOptionsBuilder() = member _.Yield(_: unit) = [ id ] member _.Run(opts) = List.fold (fun opts f -> f opts) (CustomResourceOptions()) opts - member this.Combine(lOpts, rOpts) = lOpts @ rOpts + member this.Combine(lOpts, rOpts) = + lOpts + @ rOpts + member this.For(opts, delayedOpts) = this.Combine(opts, delayedOpts ()) member _.Delay(f) = f () member _.Zero _ = () @@ -55,17 +67,21 @@ type CustomResourceOptionsBuilder() = member _.DeleteBeforeReplace(opts, value) = (fun (opts: CustomResourceOptions) -> opts.DeleteBeforeReplace <- Nullable value - opts) :: opts + opts + ) + :: opts /// The names of outputs for this resource that should be treated as secrets. This augments /// the list that the resource provider and pulumi engine already determine based on inputs /// to your resource. It can be used to mark certain outputs as a secrets on a per resource /// basis. [] - member _.AdditionalSecretOutputs(opts, value : #seq<_>) = + member _.AdditionalSecretOutputs(opts, value: #seq<_>) = (fun (opts: CustomResourceOptions) -> opts.AdditionalSecretOutputs <- ResizeArray value - opts) :: opts + opts + ) + :: opts /// The names of outputs for this resource that should be treated as secrets. This augments /// the list that the resource provider and pulumi engine already determine based on inputs @@ -74,7 +90,9 @@ type CustomResourceOptionsBuilder() = member _.AdditionalSecretOutputs(opts, value) = (fun (opts: CustomResourceOptions) -> opts.AdditionalSecretOutputs <- ResizeArray [ value ] - opts) :: opts + opts + ) + :: opts /// When provided with a resource ID, import indicates that this resource's provider should /// import its state from the cloud resource with the given ID.The inputs to the resource's @@ -84,78 +102,102 @@ type CustomResourceOptionsBuilder() = member _.ImportId(opts, value) = (fun (opts: CustomResourceOptions) -> opts.ImportId <- value - opts) :: opts + opts + ) + :: opts /// An optional existing ID to load, rather than create. [] member _.Id(opts, value) = (fun (opts: CustomResourceOptions) -> opts.Id <- input value - opts) :: opts + opts + ) + :: opts /// An optional existing ID to load, rather than create. member _.Id(opts, value) = (fun (opts: CustomResourceOptions) -> opts.Id <- io value - opts) :: opts + opts + ) + :: opts /// An optional parent resource to which this resource belongs. [] member _.Parent(opts, value) = (fun (opts: CustomResourceOptions) -> - opts.Parent <- value - opts) :: opts + opts.Parent <- value + opts + ) + :: opts /// Optional additional explicit dependencies on other resources. [] member _.DependsOn(opts, value) = (fun (opts: CustomResourceOptions) -> opts.DependsOn <- inputList value - opts) :: opts + opts + ) + :: opts /// Optional additional explicit dependencies on other resources. member _.DependsOn(opts, value) = (fun (opts: CustomResourceOptions) -> opts.DependsOn <- inputList [ input value ] - opts) :: opts + opts + ) + :: opts /// Optional additional explicit dependencies on other resources. member _.DependsOn(opts, value) = (fun (opts: CustomResourceOptions) -> opts.DependsOn <- inputList [ io value ] - opts) :: opts + opts + ) + :: opts /// Optional additional explicit dependencies on other resources. member _.DependsOn(opts, value) = (fun (opts: CustomResourceOptions) -> opts.DependsOn <- inputList (Seq.map input value) - opts) :: opts + opts + ) + :: opts /// Optional additional explicit dependencies on other resources. member _.DependsOn(opts, value) = (fun (opts: CustomResourceOptions) -> opts.DependsOn <- inputList (Seq.map io value) - opts) :: opts + opts + ) + :: opts /// When set to true, protect ensures this resource cannot be deleted. [] member _.Protect(opts, value) = (fun (opts: CustomResourceOptions) -> opts.Protect <- Nullable value - opts) :: opts + opts + ) + :: opts /// Ignore changes to any of the specified properties. [] - member _.IgnoreChanges(opts, value : #seq<_>) = + member _.IgnoreChanges(opts, value: #seq<_>) = (fun (opts: CustomResourceOptions) -> opts.IgnoreChanges <- ResizeArray value - opts) :: opts + opts + ) + :: opts /// Ignore changes to any of the specified properties. member _.IgnoreChanges(opts, value) = (fun (opts: CustomResourceOptions) -> opts.IgnoreChanges <- ResizeArray [ value ] - opts) :: opts + opts + ) + :: opts /// An optional version, corresponding to the version of the provider plugin that should be /// used when operating on this resource. This version overrides the version information @@ -164,7 +206,9 @@ type CustomResourceOptionsBuilder() = member _.Version(opts, value) = (fun (opts: CustomResourceOptions) -> opts.Version <- value - opts) :: opts + opts + ) + :: opts /// An optional provider to use for this resource's CRUD operations. If no provider is /// supplied, the default provider for the resource's package will be used. The default @@ -177,77 +221,98 @@ type CustomResourceOptionsBuilder() = member _.Provider(opts, value) = (fun (opts: CustomResourceOptions) -> opts.Provider <- value - opts) :: opts + opts + ) + :: opts - member _.Yield(value) = - [fun (opts: CustomResourceOptions) -> + member _.Yield(value) = [ + fun (opts: CustomResourceOptions) -> opts.CustomTimeouts <- value - opts] + opts + ] /// Optional list of transformations to apply to this resource during construction.The /// transformations are applied in order, and are applied prior to transformation applied to /// parents walking from the resource up to the stack. [] - member _.ResourceTransformations(opts, value : #seq<_>) = + member _.ResourceTransformations(opts, value: #seq<_>) = (fun (opts: CustomResourceOptions) -> opts.ResourceTransformations <- ResizeArray value - opts) :: opts - + opts + ) + :: opts + /// Optional list of transformations to apply to this resource during construction.The /// transformations are applied in order, and are applied prior to transformation applied to /// parents walking from the resource up to the stack. member _.ResourceTransformations(opts, value) = (fun (opts: CustomResourceOptions) -> opts.ResourceTransformations <- ResizeArray [ value ] - opts) :: opts + opts + ) + :: opts /// An optional list of aliases to treat this resource as matching. [] - member _.Aliases(opts, value : #seq<_>) = + member _.Aliases(opts, value: #seq<_>) = (fun (opts: CustomResourceOptions) -> opts.Aliases <- ResizeArray value - opts) :: opts + opts + ) + :: opts /// An optional list of aliases to treat this resource as matching. member _.Aliases(opts, value) = (fun (opts: CustomResourceOptions) -> opts.Aliases <- ResizeArray [ input value ] - opts) :: opts + opts + ) + :: opts /// An optional list of aliases to treat this resource as matching. member _.Aliases(opts, value) = (fun (opts: CustomResourceOptions) -> opts.Aliases <- ResizeArray [ io value ] - opts) :: opts + opts + ) + :: opts /// An optional list of aliases to treat this resource as matching. member _.Aliases(opts, value) = (fun (opts: CustomResourceOptions) -> - opts.Aliases <- ResizeArray (Seq.map input value) - opts) :: opts + opts.Aliases <- ResizeArray(Seq.map input value) + opts + ) + :: opts /// An optional list of aliases to treat this resource as matching. member _.Aliases(opts, value) = (fun (opts: CustomResourceOptions) -> - opts.Aliases <- ResizeArray (Seq.map io value) - opts) :: opts + opts.Aliases <- ResizeArray(Seq.map io value) + opts + ) + :: opts /// The URN of a previously-registered resource of this type to read from the engine. [] member _.Urn(opts, value) = (fun (opts: CustomResourceOptions) -> opts.Urn <- value - opts) :: opts + opts + ) + :: opts /// Changes to any of these property paths will force a replacement. If this list /// includes `"*"`, changes to any properties will force a replacement. Initialization /// errors from previous deployments will require replacement instead of update only if /// `"*"` is passed. [] - member _.ReplaceOnChanges(opts, value : #seq<_>) = + member _.ReplaceOnChanges(opts, value: #seq<_>) = (fun (opts: CustomResourceOptions) -> opts.ReplaceOnChanges <- ResizeArray value - opts) :: opts + opts + ) + :: opts /// Changes to any of these property paths will force a replacement. If this list /// includes `"*"`, changes to any properties will force a replacement. Initialization @@ -256,7 +321,9 @@ type CustomResourceOptionsBuilder() = member _.ReplaceOnChanges(opts, value) = (fun (opts: CustomResourceOptions) -> opts.ReplaceOnChanges <- ResizeArray [ value ] - opts) :: opts + opts + ) + :: opts /// An optional URL, corresponding to the url from which the provider plugin that should be /// used when operating on this resource is downloaded from. This URL overrides the download URL @@ -265,13 +332,17 @@ type CustomResourceOptionsBuilder() = member _.PluginDownloadURL(opts, value) = (fun (opts: CustomResourceOptions) -> opts.PluginDownloadURL <- value - opts) :: opts + opts + ) + :: opts /// If set to True, the providers Delete method will not be called for this resource. [] member _.RetainOnDelete(opts, value) = (fun (opts: CustomResourceOptions) -> opts.RetainOnDelete <- Nullable value - opts) :: opts + opts + ) + :: opts let customResourceOptions = CustomResourceOptionsBuilder() diff --git a/Pulumi.FSharp.Core/FAKE.yml b/src/Pulumi.FSharp.Core/FAKE.yml similarity index 100% rename from Pulumi.FSharp.Core/FAKE.yml rename to src/Pulumi.FSharp.Core/FAKE.yml diff --git a/src/Pulumi.FSharp.Core/OutputBuilder.fs b/src/Pulumi.FSharp.Core/OutputBuilder.fs new file mode 100644 index 0000000..a3548f2 --- /dev/null +++ b/src/Pulumi.FSharp.Core/OutputBuilder.fs @@ -0,0 +1,27 @@ +module Pulumi.FSharp.Outputs + +open Pulumi +open System.Threading.Tasks + +type OutputBuilder internal (isSecret) = + let create (value: 'a) = + match isSecret with + | true -> Output.CreateSecret<'a>(value) + | false -> Output.Create<'a>(value) + + member __.Return(x: 'a) = create x + + member __.Bind(comp: Output<'a>, func: 'a -> Output<'b>) = comp.Apply<'b>(func) + + member this.Bind(comp: Task<'a>, func: 'a -> Output<'b>) = + this.Bind( + (match isSecret with + | false -> Output.Create<'a>(comp) + | true -> Output.CreateSecret<'a>(comp)), + func + ) + + member __.ReturnFrom(v: Output<_>) = v + +let output = OutputBuilder(isSecret = false) +let secretOutput = OutputBuilder(isSecret = true) diff --git a/src/Pulumi.FSharp.Core/Pulumi.FSharp.Core.fsproj b/src/Pulumi.FSharp.Core/Pulumi.FSharp.Core.fsproj new file mode 100644 index 0000000..b6323ef --- /dev/null +++ b/src/Pulumi.FSharp.Core/Pulumi.FSharp.Core.fsproj @@ -0,0 +1,18 @@ + + + + net8.0 + fsharp pulumi azure + NU1605,NU1608 + true + + + + + + + + + + + diff --git a/src/Pulumi.FSharp.Core/build.fsx b/src/Pulumi.FSharp.Core/build.fsx new file mode 100644 index 0000000..5cb582e --- /dev/null +++ b/src/Pulumi.FSharp.Core/build.fsx @@ -0,0 +1,119 @@ +#r "paket: +nuget FSharp.Core 4.7.2 +nuget Fake.DotNet.Cli +nuget Fake.IO.FileSystem +nuget Fake.BuildServer.TeamFoundation +nuget Fake.Core.CommandLineParsing +nuget Fake.Core.Xml +nuget Fake.Core.Target //" +#load ".fake/build.fsx/intellisense.fsx" +#nowarn "52" + +open Fake.IO.Globbing.Operators +open Fake.Core.TargetOperators +open Fake.BuildServer +open Fake.DotNet +open Fake.Core +open System.IO + +BuildServer.install [ TeamFoundation.Installer ] + +let args = + Context.forceFakeContext().Arguments + |> Array.ofList + |> Docopt( + """ +usage: dotnet_fake_run_build.fsx [options] + +options: + -t + """ + ) + .Parse + +let getTarget args = + match Map.tryFind "-t" args with + | Some(Argument t) -> t + | _ -> "Default" + +let getProjectFile () = + !! "**/Pulumi.FSharp.Core.fsproj" + |> Seq.head + +Target.create + "Install" + (fun _ -> + DotNet.Options.Create() + |> DotNet.install DotNet.Versions.FromGlobalJson + |> ignore + ) + +Target.create + "Build" + (fun _ -> + let buildOptions options : DotNet.BuildOptions = { + options with + Common = { + options.Common with + Verbosity = Some DotNet.Verbosity.Quiet + } + NoLogo = true + } + + getProjectFile () + |> DotNet.build buildOptions + ) + +Target.create + "Pack" + (fun _ -> + getProjectFile () + |> DotNet.pack (fun po -> { + po with + MSBuildParams = { + po.MSBuildParams with + DisableInternalBinLog = true + } + }) + ) + +Target.create + "Push" + (fun _ -> + let vaultFile = + Environment.environVarOrNone "FAKEVAULTFILE_SECUREFILEPATH" + |> Option.defaultValue "Pulumi.FSharp.Extensions.vault.json" + |> FileInfo + + let vault = + match Vault.fromFakeEnvironmentOrNone (), vaultFile.Exists with + | Some vault, _ -> vault + | None, true -> + vaultFile.OpenText().ReadToEnd() + |> Vault.fromJson + | None, false -> failwith "Unsupported source for secrets" + + let pushOptions options : DotNet.NuGetPushOptions = { + options with + PushParams = { + options.PushParams with + ApiKey = Vault.tryGet "nuGetApiKey" vault + Source = Some "https://api.nuget.org/v3/index.json" + } + } + + !! "**/Pulumi.FSharp.Core.*.nupkg" + |> Seq.exactlyOne + |> DotNet.nugetPush pushOptions + ) + +Target.create "Default" ignore + +"Install" +==> "Pack" +=?> ("Push", not BuildServer.isLocalBuild) +==> "Default" + +args +|> getTarget +|> Target.runOrDefaultWithArguments diff --git a/Pulumi.FSharp.Core/build.fsx.lock b/src/Pulumi.FSharp.Core/build.fsx.lock similarity index 100% rename from Pulumi.FSharp.Core/build.fsx.lock rename to src/Pulumi.FSharp.Core/build.fsx.lock diff --git a/src/Pulumi.FSharp.Core/paket.references b/src/Pulumi.FSharp.Core/paket.references new file mode 100644 index 0000000..2db73ac --- /dev/null +++ b/src/Pulumi.FSharp.Core/paket.references @@ -0,0 +1,2 @@ +group Providers + Pulumi.FSharp \ No newline at end of file diff --git a/src/Pulumi.FSharp.Myriad/AstHelpers.fs b/src/Pulumi.FSharp.Myriad/AstHelpers.fs new file mode 100644 index 0000000..85831ae --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/AstHelpers.fs @@ -0,0 +1,337 @@ +module AstHelpers + +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTrivia +open FSharp.Compiler.Text +open Core +open Myriad.Core.Ast +open Myriad.Core.AstExtensions + +type SimplePat = + /// str + static member id(str) = + SynSimplePat.Id(Ident.Create(str), None, false, false, false, range.Zero) + + static member hashTyped(str, type': string) = + SynSimplePat.CreateTyped( + Ident.Create str, + SynType.HashConstraint(SynType.CreateLongIdent(type'), range.Zero) + ) + + static member typed(str, type': string) = + SynSimplePat.Typed(SimplePat.id (str), SynType.CreateLongIdent(type'), range.Zero) + +type SynPat with + + static member CreateTuple(args: SynPat list) = SynPat.Tuple(false, args, Range.Zero) + +type Pat = + static member tuple(left, right) = + SynPat.CreateTuple( + [ + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(left), []) + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(right), []) + ] + ) + + static member tuple(one, two, three) = + SynPat.CreateTuple( + [ + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(one), []) + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(two), []) + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(three), []) + ] + ) + + static member tuple(left: SynPat, right: SynPat) = + SynPat.CreateTuple( + [ + left + right + ] + ) + + static member paren(pat: SynPat) = SynPat.CreateParen(pat) + + static member ident(str) = + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(str), []) + + static member null' = SynPat.Null(range.Zero) + + static member wild = SynPat.Wild(range.Zero) + + static member typed(name, typeName: string) = + SynPat.Typed(Pat.ident (name), SynType.CreateLongIdent(typeName), range.Zero) + |> SynPat.CreateParen + +type Expr = + /// str + static member ident(str) = SynExpr.CreateIdent(Ident.Create(str)) + + /// str.str + static member longIdent(str) = + SynExpr.CreateLongIdent(LongIdentWithDots.CreateString(str)) + + /// (exp) + static member paren(exp) = SynExpr.CreateParen(exp) + + /// () + static member unit = SynExpr.CreateUnit + + /// null + static member null' = SynExpr.CreateNull + + /// (left, right) + static member tuple(left, right) = + SynExpr.CreateTuple( + [ + left + right + ] + ) + + /// (left, right) + static member tuple(one, two, three) = + SynExpr.CreateTuple( + [ + one + two + three + ] + ) + + /// (a, b, c, ...) + static member tuple(exps) = SynExpr.CreateTuple(exps) + + /// [ ... ] + static member list(exps) = + SynExpr.ArrayOrList(false, exps, range.Zero) + + /// [ ... ] + static member list(idents) = + SynExpr.ArrayOrList( + false, + idents + |> List.map Expr.ident, + range.Zero + ) + + /// exp1 + /// exp2 + /// ... + static member sequential(exps) = SynExpr.CreateSequential(exps) + + /// func arg + static member app(func, arg) = SynExpr.CreateApp(func, arg) + + /// func arg1 arg2 ... + static member app(func: SynExpr, args: SynExpr list) = + match args with + | [] -> Expr.app (func, Expr.unit) + | [ x ] -> Expr.app (func, x) + | x :: xs -> Expr.app (Expr.app (func, x), xs) + + /// func arg1 arg2 ... + static member app(func: string, args: SynExpr list) = + Expr.app ((Expr.longIdent (func): SynExpr), args) + + /// func arg + static member app(func: string, arg: string) = + Expr.app (Expr.longIdent (func), Expr.ident (arg)) + + /// func arg + static member app(func: string, arg: SynExpr) = Expr.app (Expr.longIdent (func), arg) + + /// func (arg1, arg2, ...) + static member appTuple(func: string, args) = + Expr.app ( + func, + Expr.paren ( + Expr.tuple ( + args + |> List.map Expr.ident + ) + ) + ) + + static member appTuple(func: SynExpr, args) = + Expr.app ( + func, + Expr.paren ( + Expr.tuple ( + args + |> List.map Expr.ident + ) + ) + ) + + static member appTuple(func: string, args: SynExpr list) = + Expr.app (func, Expr.paren (Expr.tuple args)) + + static member match'(expr, clauses) = SynExpr.CreateMatch(expr, clauses) + + /// value + static member const'(value) = SynExpr.CreateConstString(value) + + /// failwith msg + static member failwith(msg) = + Expr.app ("failwith", Expr.const' (msg)) + + static member let'(name, args: SynPat list, exp) = + SynExpr.LetOrUse( + false, + false, + [ + SynBinding.Let( + pattern = SynPat.CreateLongIdent(LongIdentWithDots.CreateString(name), args), + expr = exp + ) + ], + Expr.unit, + range.Zero, + { InKeyword = None } + ) + + static member let'(name, args, exp) = + SynExpr.LetOrUse( + false, + false, + [ + SynBinding.Let( + pattern = + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString(name), + (args + |> List.map Pat.ident) + ), + expr = exp + ) + ], + Expr.unit, + range.Zero, + { InKeyword = None } + ) + + static member set(identString, exp) = + SynExpr.Set(Expr.longIdent (identString), exp, range.Zero) + + static member methodCall(identString, exps) = + SynExpr.CreateInstanceMethodCall( + LongIdentWithDots.CreateString(identString), + Expr.paren (Expr.tuple (exps)) + ) + + static member lambda(args: SynSimplePat list, exp: SynExpr) = + let mapArgs = + function + | SynSimplePat.Id(x, _, _, _, _, _) -> + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(x.idText), []) + | SynSimplePat.Typed(SynSimplePat.Id(ident, _, _, _, _, _), targetType, _) -> + SynPat.CreateParen( + SynPat.CreateTyped( + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(ident.idText), []), + targetType + ) + ) + | x -> + sprintf "%A" x + |> failwith + + let pats = + args + |> List.map mapArgs + + let pat = + match pats with + | [] -> SynPat.CreateTuple(pats) + | [ _ ] -> SynPat.CreateTuple(pats) + | _ -> SynPat.CreateParen(SynPat.CreateTuple(pats)) + + SynExpr.CreateLambda([ pat ], exp) + + static member lambda(args: string list, exp) = + SynExpr.CreateLambda( + args + |> List.map (fun x -> SynPat.CreateLongIdent(LongIdentWithDots.CreateString(x), [])), + exp + ) + +//match args with +//| [ ] -> Expr.lambda(List.empty, exp) +//| [x] -> Expr.lambda([ SimplePat.id(x) ], exp) +//| x :: xs -> Expr.lambda([ SimplePat.id(x) ], Expr.lambda(xs, exp)) + +type Match = + static member clause(pat, expr) = + SynMatchClause.SynMatchClause( + pat, + None, + expr, + range.Zero, + DebugPointAtTarget.No, + { + ArrowRange = Some range.Zero + BarRange = Some range.Zero + } + ) + +type Namespace = + static member namespace'(name, content) = + SynModuleOrNamespace.CreateNamespace(Ident.CreateLong name, decls = content) + +type Attribute = + static member attribute(name) = + SynAttributeList.Create(SynAttribute.Create(name)) + +type Module = + static member module'(name, content, attributes) = + let componentInfo = + SynComponentInfo.Create([ Ident.Create name ], attributes = attributes) + + SynModuleDecl.NestedModule( + componentInfo, + false, + content, + false, + Range.Zero, + { + EqualsRange = Some Range.Zero + ModuleKeyword = Some Range.Zero + } + ) + + static member module'(name, content) = Module.module' (name, content, []) + + static member autoOpenModule(name, content) = + Module.module' (name, content, [ Attribute.attribute ("AutoOpen") ]) + + static member open'(namespaceOrModule) = + SynOpenDeclTarget.ModuleOrNamespace( + LongIdentWithDots.CreateString(namespaceOrModule).Lid, + range.Zero + ) + |> SynModuleDecl.CreateOpen + + static member type'(name, content) = + let t = + SynTypeDefn.SynTypeDefn( + SynComponentInfo.Create(Ident.CreateLong(name)), + SynTypeDefnRepr.ObjectModel( + SynTypeDefnKind.Unspecified, + [ SynMemberDefn.CreateImplicitCtor() ], + Range.Zero + ), + content, + None, + Range.Zero, + { + SynTypeDefnTrivia.TypeKeyword = Some Range.Zero + EqualsRange = Some Range.Zero + WithKeyword = None + } + ) + + SynModuleDecl.Types([ t ], Range.Zero) + +type Type = + static member ctor() = SynMemberDefn.CreateImplicitCtor() diff --git a/src/Pulumi.FSharp.Myriad/Attribute.fs b/src/Pulumi.FSharp.Myriad/Attribute.fs new file mode 100644 index 0000000..ed3d776 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Attribute.fs @@ -0,0 +1,19 @@ +module AstAttribute + +open FSharp.Compiler.Text +open FSharp.Compiler.Syntax +open Myriad.Core.AstExtensions + +let createAttribute name = + SynAttributeList.Create(SynAttribute.Create(name)) + +let createAttributeWithArg (name: string) (arg: string) = + let o: SynAttribute = { + TypeName = LongIdentWithDots.CreateString(name) + ArgExpr = SynExpr.CreateParen(SynExpr.CreateConstString(arg)) + Target = None + AppliesToGetterAndSetter = false + Range = range.Zero + } + + SynAttributeList.Create(o) diff --git a/src/Pulumi.FSharp.Myriad/Builder.fs b/src/Pulumi.FSharp.Myriad/Builder.fs new file mode 100644 index 0000000..89df0bd --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Builder.fs @@ -0,0 +1,342 @@ +module AstBuilder + +open Myriad.Core.AstExtensions +open AstOperations +open AstInstance +open AstHelpers +open AstMember +open AstYield +open AstRun +open Core + +open System.Text.RegularExpressions +open FSharp.Text.RegexProvider + +// "azure:compute/virtualMachine:VirtualMachine" +// CloudProvider - Always the same for each schema (azure here) +type InfoProvider = + Regex<"(?[a-z0-9-]+):(?[A-Za-z0-9.]+)(/(?\w+))?:(?\w+)"> + +let typeInfoProvider = InfoProvider(RegexOptions.Compiled) + +type BuilderType = + | Type of InfoProvider.MatchType + | Resource of InfoProvider.MatchType + +let private argIdent = Pat.ident ("arg") + +let private argToInput = Expr.app ("input", "arg") + +let private args = Expr.ident ("args") + +let private funcIdent = Expr.ident ("func") + +let private yieldReturnExpr = Expr.list ([ Expr.ident ("id") ]) + +let private combineExpr = Expr.app ("_combine", "args") + +let private combineCrosExpr = Expr.app ("_combineCros", "args") + +let private combineArgs = Pat.ident ("args") + +let private combineMember = + createMember' None "this" "Combine" combineArgs [] combineExpr + +let private combineCrosMember = + createMember' None "this" "Combine" combineArgs [] combineCrosExpr + +let private forArgs = Pat.paren (Pat.tuple ("args", "delayedArgs")) + +let private forExpr = + Expr.methodCall ( + "this.Combine", + [ + Expr.ident ("args") + Expr.app ("delayedArgs", Expr.unit) + ] + ) + +let private forMember = createMember' None "this" "For" forArgs [] forExpr + +let private delayMember = + createMember "Delay" (Pat.ident ("f")) [] (Expr.app ("f", [])) + +let private zeroMember = createMember "Zero" Pat.wild [] Expr.unit + +let private yieldMember isType = + createYield isType yieldReturnExpr yieldReturnExpr + +let private newNameExpr = + Expr.tuple (Expr.ident ("newName"), Expr.ident ("args"), Expr.ident ("cros")) + +let private nameMember = createNameOperation newNameExpr + +let createYieldFor argsType propType = + let setExpr = + Expr.sequential ( + [ + Expr.set ( + "args." + + propType.Name, + argToInput + ) + args + ] + ) + + let expr = + Expr.list ( + [ + Expr.paren ( + Expr.sequential ( + [ + Expr.let' ("func", [ Pat.typed ("args", argsType) ], setExpr) + funcIdent + ] + ) + ) + ] + ) + + let cros = Expr.list ([ Expr.ident ("id") ]) + + [ createYield' (not propType.IsResource) argIdent expr cros ] + +let mapOperationType yieldSelector opsSelector = + function + | { + Type = PRef _ + CanGenerateYield = true + } & pt -> yieldSelector pt + | { Type = PRef _ } & pt + | { Type = PString } & pt + | { Type = PInteger } & pt + | { Type = PFloat } & pt + | { Type = PBoolean } & pt + | { Type = PArray _ } & pt + | { Type = PUnion _ } & pt + | { Type = PJson _ } & pt + | { Type = PMap _ } & pt + | { Type = PAssetOrArchive _ } & pt + | { Type = PAny _ } & pt + | { Type = PArchive _ } & pt -> opsSelector pt + +let createBuilderClass isType isComponent name pTypes = + let argsType = $"{name}Args" + + let apply varname = + let args = + match varname with + | "args" -> argsType + | _ when isComponent -> "ComponentResourceOptions" + | _ -> "CustomResourceOptions" + + Expr.app ( + "List.fold", + [ + Expr.paren ( + Expr.lambda ( + [ + varname + "f" + ], + Expr.app ("f", varname) + ) + ) + Expr.paren (createInstance args Expr.unit) + Expr.ident (varname) + ] + ) + + let resourceRunExp () = + Expr.paren (Expr.tuple (Expr.ident ("name"), (apply "args"), (apply "cros"))) + |> createInstance name + + let createOperations = + mapOperationType (createYieldFor argsType) (createOperationsFor' argsType) + + let operations = + pTypes + |> Seq.collect createOperations + + let inputListOfInput argName = + Expr.app ( + Expr.ident ("inputList"), + Expr.list ([ Expr.app (Expr.ident ("input"), Expr.ident (argName)) ]) + ) + + let inputListOfResources argName = + Expr.app ( + Expr.ident ("inputList"), + Expr.paren ( + Expr.app ( + Expr.longIdent ("Seq.map"), + Expr.app (Expr.ident ("input"), Expr.ident (argName)) + ) + ) + ) + + Module.type' ( + name + + "Builder", + [ + //Type.ctor() + + yieldMember isType + + if isType then + apply "args" + |> createRunType + else + resourceRunExp () + |> createRunResource + + if isType then combineMember else combineCrosMember + forMember + delayMember + zeroMember + + yield! if isType then [] else [ nameMember ] + + yield! operations + + if not isType then + croOperation + "DependsOn" + ResourceOptions + "Ensure this resource gets created after its dependency" + "dependency" + (inputListOfInput "dependency") + false + true + + croOperation + "DependsOn" + ResourceOptions + "Ensure this resource gets created after its dependency" + "dependency" + (inputListOfResources "dependency") + true + false + + croOperation + "Id" + ResourceOptions + "An optional existing ID to load, rather than create." + "resourceId" + (Expr.ident "resourceId") + false + true + + croOperation + "IgnoreChanges" + ResourceOptions + "If set to True, the providers Delete method will not be called for this resource." + "paths" + (Expr.ident "paths") + true + true + + croOperation + "ReplaceOnChanges" + ResourceOptions + """Changes to any of these property paths will force a replacement. If this list includes `"*"`, changes to any properties will force a replacement. Initialization errors from previous deployments will require replacement instead of update only if `"*"` is passed.""" + "paths" + (Expr.ident "paths") + true + true + + croOperation + "ResourceTransformations" + ResourceOptions + "Optional list of transformations to apply to this resource during construction.The transformations are applied in order, and are applied prior to transformation applied to parents walking from the resource up to the stack." + "transformations" + (Expr.ident "transformations") + true + true + + croOperation + "RetainOnDelete" + ResourceOptions + "If set to True, the providers Delete method will not be called for this resource." + "retain" + (Expr.ident "retain") + false + true + + croOperation + "Urn" + ResourceOptions + "The URN of a previously-registered resource of this type to read from the engine." + "urn" + (Expr.ident "urn") + false + true + + croOperation + "Protect" + ResourceOptions + "When set to true, protect ensures this resource cannot be deleted." + "isProtected" + (Expr.ident "isProtected") + false + true + + croOperation + "Parent" + ResourceOptions + "An optional parent resource to which this resource belongs." + "parent" + (Expr.ident "parent") + false + true + + // CustomResourceOptions-specific types + if not isComponent then + croOperation + "AdditionalSecretOutputs" + CustomResourceOptions + "The names of outputs for this resource that should be treated as secrets. This augments the list that the resource provider and pulumi engine already determine based on inputs to your resource. It can be used to mark certain outputs as a secrets on a per resource basis." + "outputs" + (Expr.ident "outputs") + true + true + + croOperation + "DeleteBeforeReplace" + CustomResourceOptions + "When set to `true`, indicates that this resource should be deleted before its replacement is created when replacement is necessary." + "deletedBeforeReplace" + (Expr.ident "deletedBeforeReplace") + false + true + + croOperation + "ImportId" + CustomResourceOptions + "When provided with a resource ID, import indicates that this resource's provider should import its state from the cloud resource with the given ID. The inputs to the resource's constructor must align with the resource's current state. Once a resource has been imported, the import property must be removed from the resource's options." + "resourceId" + (Expr.ident "resourceId") + false + true + + croOperation + "Provider" + ResourceOptions + "An optional provider to use for this resource's CRUD operations. If no provider is supplied, the default provider for the resource's package will be used. The default provider is pulled from the parent's provider bag (see also ComponentResourceOptions.providers)." + "resourceProvider" + (Expr.ident "resourceProvider") + false + true + + else + croOperation + "Providers" + ComponentResourceOptions + "An optional set of providers to use for child resources." + "resourceProviders" + (Expr.ident "resourceProviders") + true + true + ] + ) diff --git a/src/Pulumi.FSharp.Myriad/BuilderInstance.fs b/src/Pulumi.FSharp.Myriad/BuilderInstance.fs new file mode 100644 index 0000000..47cd0ec --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/BuilderInstance.fs @@ -0,0 +1,76 @@ +module BuilderInstance + +open FSharp.Compiler.Syntax +open AstOperations +open AstInstance +open AstBuilder +open AstLet +open Myriad.Core.AstExtensions +open Core + +let createBuilderInstance description typeName pTypes = + let isYield, ops = + Array.partition + (fun x -> + x.CanGenerateYield + && mapOperationType (fun _ -> true) (fun _ -> false) x + ) + pTypes + + let builderNames = + isYield + |> Array.map ( + function + | { Type = PRef t } -> + String.split ':' t + |> Array.last + |> toCamelCase + | x -> failwith $"{x} type should not use yield" + ) + + let listItem = sprintf " - %s" + + let title text = $"*** {text} ***" + + let builderNamesSection = + match + builderNames + |> List.ofArray + with + | [] -> [] + | bn -> + "" + :: title "Nested computational expressions" + :: (List.map listItem bn) + + let descriptionShort = + description + |> String.split '\n' + |> Array.head + + let ccTypeName = + if typeName = "Input" then + "input'" + else + typeName + |> toCamelCase + + [ + yield descriptionShort + yield "" + yield title "Operations" + yield! + ops + |> Array.map (fun x -> listItem x.OperationName) + |> Array.collect (fun x -> [| + "" + x + |]) + yield! + builderNamesSection + |> List.collect (fun x -> [ + "" + x + ]) + ] + |> createLet ccTypeName (createInstance $"{typeName}Builder" SynExpr.CreateUnit) diff --git a/src/Pulumi.FSharp.Myriad/CHANGELOG.md b/src/Pulumi.FSharp.Myriad/CHANGELOG.md new file mode 100644 index 0000000..3ec8ac2 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/CHANGELOG.md @@ -0,0 +1,42 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [3.2.0] - 2024-10-01 + +Support for `ResourceOptions`-derived types has been improved, allowing more flexible customization + +### Added +- Various custom operations that represent `ResourceOptions` in the Pulumi .NET SDK. + +### Fixed +- Fixed an issue where specific resource types could not be used as inputs to other Pulumi resources (such as in the AWS providers >6.49) +- Some providers such as AWS and Docker, which use inconsistent casing for resource names, now handle names case-insensitivitely. + +## [3.1.7] - 2024-06-24 + +Pulumi providers that use `ComponentResource` as a base class are now interpreted correctly by the Myriad compiler extension. + +## [3.1.6] - 2024-05-31 + +Providers now use a dedicated FAKE dependency group to enable detection of updated providers via GitOps + +### Changed +- Provider dependencies moved from `Main` group to `Providers`. + +## [3.1.5] - 2024-05-31 + +Updated the project to use modern build tooling. + +### Fixed +- Numbers in provider names (e.g. `auth0`) no longer break the plugin. +- GCP resources that use slashes as namespacing (e.g. `gcp:privilegedaccessmanager/entitlement`) no longer break the plugin. + +### Added +- DigitalOcean provider +- Auth0 provider +- Support for Kubernetes `ConfigFile` and `ConfigGroup` types \ No newline at end of file diff --git a/src/Pulumi.FSharp.Myriad/Core.fs b/src/Pulumi.FSharp.Myriad/Core.fs new file mode 100644 index 0000000..ea38a07 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Core.fs @@ -0,0 +1,27 @@ +module Core + +open System +open FSharp.Compiler.Syntax +open Myriad.Core.Ast +open Myriad.Core.AstExtensions + +let private (|FirstLetter|) (p: string) = p[0], p.Substring(1) + +let private changeInitial change value = + let (FirstLetter(x, xs)) = value + + sprintf "%c%s" (change x) xs + +let toCamelCase = changeInitial Char.ToLower + +let toPascalCase = changeInitial Char.ToUpper + +let createPattern name args = + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(name), args) + +let (|Lazy|) (lazy': Lazy<'a>) = lazy'.Value + +module String = + let split (char: char) (value: string) = value.Split(char) + + let contains (subString: string) (value: string) = value.Contains(subString) diff --git a/Pulumi.FSharp.Myriad/Debug.fs b/src/Pulumi.FSharp.Myriad/Debug.fs similarity index 62% rename from Pulumi.FSharp.Myriad/Debug.fs rename to src/Pulumi.FSharp.Myriad/Debug.fs index bfd952e..73c7dc3 100644 --- a/Pulumi.FSharp.Myriad/Debug.fs +++ b/src/Pulumi.FSharp.Myriad/Debug.fs @@ -8,18 +8,20 @@ type private Filter<'a> = | Exclude of 'a list type private Filters = { - Providers: Filter - Resources: Filter - Types: Filter - } + Providers: Filter + Resources: Filter + Types: Filter +} let private azureFilters = { - Types = Include [ + Types = + Include [ "WindowsVirtualMachineSourceImageReference" "WindowsVirtualMachineOsDisk" "NetworkInterfaceIpConfiguration" ] - Resources = Include [ + Resources = + Include [ "Blob" "WindowsVirtualMachine" "NetworkInterface" @@ -30,16 +32,18 @@ let private azureFilters = { "Account" "Container" ] - Providers = Include [ + Providers = + Include [ "compute" "storage" "network" "core" - ] - } + ] +} let private azureNativeFilters = { - Types = Include [ + Types = + Include [ "VirtualMachineSourceImageReference" "VirtualMachineOsDisk" "NetworkInterfaceIPConfiguration" @@ -55,7 +59,8 @@ let private azureNativeFilters = { "Sku" "ManagedDiskParameters" ] - Resources = Include [ + Resources = + Include [ "Blob" "VirtualMachine" "NetworkInterface" @@ -69,41 +74,35 @@ let private azureNativeFilters = { "BlobContainer" "StorageAccount" ] - Providers = Include [ + Providers = + Include [ "compute" "storage" "network" "core" "resources" - ] - } + ] +} let private azureAdFilters = { - Types = Include [ - ] - Resources = Include [ + Types = Include [] + Resources = + Include [ "Application" "Group" ] - Providers = Include [ - "index" - ] - } + Providers = Include [ "index" ] +} let private awsFilters = { - Types = Include [ - "BucketWebsite" - ] - Resources = Include [ - "Bucket" - ] - Providers = Include [ - "s3" - ] - } + Types = Include [ "BucketWebsite" ] + Resources = Include [ "Bucket" ] + Providers = Include [ "s3" ] +} let private kubernetesFilters = { - Types = Include [ + Types = + Include [ "ServiceSpecType" "ServiceSpec" "DeploymentSpec" @@ -114,52 +113,73 @@ let private kubernetesFilters = { "ContainerPort" "ObjectMeta" ] - Resources = Include [ - "Deployment" - ] - Providers = Include [ + Resources = Include [ "Deployment" ] + Providers = + Include [ "core/v1" "apps/v1" - "meta/v1" ] - } + "meta/v1" + ] +} let private merge left right = match left, right with - | Include li, Include ri -> li @ ri |> Include - | Exclude le, Include re -> le @ re |> Exclude - | _ -> failwith "Using include and exclude debug filters together is not supported" + | Include li, Include ri -> + li @ ri + |> Include + | Exclude le, Include re -> + le @ re + |> Exclude + | _ -> failwith "Using include and exclude debug filters together is not supported" let private join filtersList = let reduce select = - filtersList |> List.map select |> List.reduce merge - + filtersList + |> List.map select + |> List.reduce merge + { - Types = reduce (fun f -> f.Types) + Types = reduce (fun f -> f.Types) Resources = reduce (fun f -> f.Resources) Providers = reduce (fun f -> f.Providers) } let private isDebug = false -let private filters = join [ azureFilters; awsFilters; kubernetesFilters; azureAdFilters; azureNativeFilters ] + +let private filters = + join [ + azureFilters + awsFilters + kubernetesFilters + azureAdFilters + azureNativeFilters + ] let private typeSelector builderType = match (builderType, filters.Types, filters.Resources) with - | Type t, Include it, _ - | Resource t, _ , Include it -> List.contains t.ResourceType.Value it - | Type t, Exclude et, _ - | Resource t, _ , Exclude et -> not <| List.contains t.ResourceType.Value et + | Type t, Include it, _ + | Resource t, _, Include it -> List.contains t.ResourceType.Value it + | Type t, Exclude et, _ + | Resource t, _, Exclude et -> + not + <| List.contains t.ResourceType.Value et let private providerSelector provider = match filters.Providers with | Include ps -> List.contains provider ps - | Exclude ps -> not <| List.contains provider ps + | Exclude ps -> + not + <| List.contains provider ps let private debugTupleArrayFilter filter values = - values |> - if isDebug then - Array.filter (fst >> filter) - else - id + values + |> if isDebug then + Array.filter ( + fst + >> filter + ) + else + id let debugFilterTypes types = debugTupleArrayFilter typeSelector types diff --git a/src/Pulumi.FSharp.Myriad/Generator.fs b/src/Pulumi.FSharp.Myriad/Generator.fs new file mode 100644 index 0000000..55c4ec0 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Generator.fs @@ -0,0 +1,82 @@ +module Pulumi.FSharp.Myriad + +open AstNamespace +open IndexModule +open Myriad.Core +open AstModules +open System.Xml +open System.IO +open Schema +open Paket + +[] +type PulumiFSharpGenerator() = + + interface IMyriadGenerator with + member this.Generate(context) = + + let getVersionFromFsproj (projectFile: FileInfo) (provider: string) = + let fsproj: XmlDocument = XmlDocument() in + do fsproj.Load(projectFile.OpenText()) + + fsproj.SelectNodes("/Project/ItemGroup") + |> Seq.cast + |> Seq.collect (fun y -> + y.SelectNodes("PackageReference") + |> Seq.cast + ) + |> Seq.pick (fun x -> + if x.Attributes["Include"].Value = $"Pulumi.{provider}" then + x.Attributes["Version"].Value + |> Some + else + None + ) + + let projectFile = + FileInfo(context.InputFilename).Directory.EnumerateFiles("*.fsproj") + |> Seq.exactlyOne + + let provider = + let providerName = projectFile.Name["Pulumi.FSharp.".Length .. ^".fsproj".Length] + let providerNameOverride = Map.ofList [ "AzureNativeV2", "AzureNative" ] + + providerNameOverride + |> Map.tryFind providerName + |> Option.defaultValue providerName + + let paketDeps = + FileInfo(context.InputFilename).DirectoryName + |> Paket.Dependencies.TryLocate + + let paketProviderVersion = + paketDeps + |> Option.map (fun deps -> + deps + .GetInstalledPackageModel(Some "Providers", $"Pulumi.{provider}") + .PackageVersion.Normalize() + ) + + + let version = + match paketProviderVersion with + | Some version -> version + | None -> getVersionFromFsproj projectFile provider + + let providerRepositoryNameOverride = + [ "AzureNative", "azure-native" ] + |> Map.ofList + + let providerRepository = + providerRepositoryNameOverride + |> Map.tryFind provider + |> Option.defaultValue provider + + loadSchema providerRepository version + |> createTypes + |> createModules provider + |> createNamespace + |> List.singleton + |> Output.Ast + + member this.ValidInputExtensions = seq { ".fs" } diff --git a/src/Pulumi.FSharp.Myriad/IndexModule.fs b/src/Pulumi.FSharp.Myriad/IndexModule.fs new file mode 100644 index 0000000..90c17c6 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/IndexModule.fs @@ -0,0 +1,261 @@ +module IndexModule + +open FSharp.Compiler.Syntax +open AstHelpers +open AstModules +open FSharp.Compiler.Text +open Myriad.Core.Ast +open Myriad.Core.AstExtensions +open Core + +type private Namespace = { + Name: string + SubNamespaceName: string option + Content: seq +} + +type private SubNamespace = { + Name: string option + Content: seq +} + +let createModules provider ((indexTypes, qualifiedTypes): PulumiModule list * PulumiModule list) = + let groupSub contentList = + contentList + |> List.groupBy (fun ns -> ns.SubNamespaceName) + |> List.map (fun (subName, content) -> { + Name = subName + Content = + content + |> Seq.collect (fun c -> c.Content) + }) + + let createSubmodule subName rootNamespace content = + createModule' + subName + [ + $"{provider}.{rootNamespace}.{subName}" + $"{provider}.Types.Inputs.{rootNamespace}.{subName}" + ] + content + + let createSubmodules rootNamespace = + Seq.collect ( + function + | { + Content = content + SubNamespace.Name = None + } -> content + | { + Content = content + Name = Some subName + } -> seq { createSubmodule subName rootNamespace content } + ) + + let qualifiedTypesModules = + qualifiedTypes + |> List.map ( + (fun qualifiedTypeModule -> + (String.split '.' qualifiedTypeModule.ResourceProviderNamespace.Value, + qualifiedTypeModule.Content) + ) + >> (function + | [| rootNamespace |], content -> { + Name = rootNamespace + SubNamespaceName = None + Content = content + } + | [| rootNamespace; subNamespace |], content -> { + Name = rootNamespace + SubNamespaceName = Some subNamespace + Content = content + } + | _ -> failwith "Too many nested namespaces") + ) + |> List.groupBy (fun rootNamespace -> rootNamespace.Name) + |> List.map (fun (rootNamespaceName, content) -> + groupSub content + |> createSubmodules rootNamespaceName + |> createModule' rootNamespaceName [ $"{provider}.{rootNamespaceName}" ] + ) + + let indexTypesAsts = + indexTypes + |> Seq.collect (fun x -> x.Content) + + let letCombineImplementation = + let fromRcd = + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString("_combine"), + [ + Pat.paren ( + Pat.tuple ( + Pat.paren (Pat.tuple ("rName", "rArgs")), + Pat.paren (Pat.tuple ("lName", "lArgs")) + ) + ) + ] + ) + |> ignore // Replace below with this + + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString("_combine"), + [ + SynPat.CreateParen( + SynPat.Tuple( + false, + [ + SynPat.CreateParen( + SynPat.Tuple( + false, + [ + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString("rName"), + [] + ) + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString("rArgs"), + [] + ) + ], + range.Zero + ) + ) + SynPat.CreateParen( + SynPat.Tuple( + false, + [ + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString("lName"), + [] + ) + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString("lArgs"), + [] + ) + ], + range.Zero + ) + ) + ], + Range.Zero + ) + ) + ] + ) + + let matchExpr = + Expr.paren ( + Expr.match' ( + Expr.tuple (Expr.ident ("lName"), Expr.ident ("rName")), + [ + Match.clause (Pat.tuple (Pat.null', Pat.null'), Expr.null') + Match.clause ( + Pat.tuple (Pat.null', Pat.ident ("name")), + Expr.ident ("name") + ) + Match.clause ( + Pat.tuple (Pat.ident ("name"), Pat.null'), + Expr.ident ("name") + ) + Match.clause (Pat.wild, Expr.failwith ("Duplicate name")) + ] + ) + ) + + let combineExpr = + Expr.tuple ( + matchExpr, + Expr.paren ( + Expr.app ( + "List.concat", + (Expr.list [ + "lArgs" + "rArgs" + ]) + ) + ) + ) + + let expr = combineExpr + + SynModuleDecl.CreateLet( + [ SynBinding.Let(SynAccess.Private, pattern = fromRcd, expr = expr) ] + ) + + let letCombineCrosImplementation = + let fromRcd = + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString("_combineCros"), + [ + Pat.paren ( + Pat.tuple ( + Pat.paren (Pat.tuple ("rName", "rArgs", "rCros")), + Pat.paren (Pat.tuple ("lName", "lArgs", "lCros")) + ) + ) + ] + ) + + let matchExpr = + Expr.paren ( + Expr.match' ( + Expr.tuple (Expr.ident ("lName"), Expr.ident ("rName")), + [ + Match.clause (Pat.tuple (Pat.null', Pat.null'), Expr.null') + Match.clause ( + Pat.tuple (Pat.null', Pat.ident ("name")), + Expr.ident ("name") + ) + Match.clause ( + Pat.tuple (Pat.ident ("name"), Pat.null'), + Expr.ident ("name") + ) + Match.clause (Pat.wild, Expr.failwith ("Duplicate name")) + ] + ) + ) + + let combineExpr = + Expr.tuple ( + matchExpr, + Expr.paren ( + Expr.app ( + "List.concat", + (Expr.list [ + "lArgs" + "rArgs" + ]) + ) + ), + Expr.paren ( + Expr.app ( + "List.concat", + (Expr.list [ + "lCros" + "rCros" + ]) + ) + ) + ) + + let expr = combineExpr + + SynModuleDecl.CreateLet( + [ SynBinding.Let(SynAccess.Private, pattern = fromRcd, expr = expr) ] + ) + + Module.module' ( + provider, + [ + Module.open' ($"Pulumi.{provider}") + + letCombineImplementation + + letCombineCrosImplementation + + yield! indexTypesAsts + + yield! qualifiedTypesModules + ] + ) diff --git a/Pulumi.FSharp.Myriad/Instance.fs b/src/Pulumi.FSharp.Myriad/Instance.fs similarity index 50% rename from Pulumi.FSharp.Myriad/Instance.fs rename to src/Pulumi.FSharp.Myriad/Instance.fs index 7db475e..6ace716 100644 --- a/Pulumi.FSharp.Myriad/Instance.fs +++ b/src/Pulumi.FSharp.Myriad/Instance.fs @@ -5,7 +5,7 @@ open Myriad.Core.AstExtensions let createInstance name args = let identifier = - LongIdentWithDots.CreateString name |> - SynExpr.CreateLongIdent - - SynExpr.CreateApp(identifier, args) \ No newline at end of file + LongIdentWithDots.CreateString name + |> SynExpr.CreateLongIdent + + SynExpr.CreateApp(identifier, args) diff --git a/src/Pulumi.FSharp.Myriad/Let.fs b/src/Pulumi.FSharp.Myriad/Let.fs new file mode 100644 index 0000000..d7d893f --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Let.fs @@ -0,0 +1,15 @@ +module AstLet + +open FSharp.Compiler.Syntax +open FSharp.Compiler.Xml +open Myriad.Core.Ast +open Myriad.Core.AstExtensions + +let createLet name expr (docs: string list) = + SynModuleDecl.CreateLet [ + SynBinding.Let( + pattern = SynPat.CreateLongIdent(LongIdentWithDots.CreateString name, []), + expr = expr, + xmldoc = PreXmlDoc.Create(docs) + ) + ] diff --git a/src/Pulumi.FSharp.Myriad/Member.fs b/src/Pulumi.FSharp.Myriad/Member.fs new file mode 100644 index 0000000..ec454fb --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Member.fs @@ -0,0 +1,75 @@ +module AstMember + +open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTrivia +open FSharp.Compiler.Text +open Core +open FSharp.Compiler.Xml +open Myriad.Core.Ast +open Myriad.Core.AstExtensions + +let createMember' xmlDoc this name args attrs expr = + + //let memberFlags : MemberFlags = + //let b : SynBindingRcd = + // { + // ValData = SynValData(Some memberFlags, SynValInfo([], SynArgInfo(SynAttributes.Empty, false, None)), None) + // Pat = SynPat.LongIdent(LongIdentWithDots([mkId "x"; mkId "Points"], [range.Zero]), None, None, SynConstructorArgs.Pats[], None, range.Zero) + // } + let memberFlag: SynMemberFlags = { + IsInstance = true + IsDispatchSlot = false + IsOverrideOrExplicitImpl = false + IsFinal = false + MemberKind = SynMemberKind.Member + Trivia = { + MemberRange = Some Range.Zero + OverrideRange = None + AbstractRange = None + StaticRange = None + DefaultRange = None + } + } + + let argsPat = + match args with + | SynPat.Paren _ + | SynPat.Wild _ -> args + | _ -> SynPat.Paren(args, Range.Zero) + + SynBinding.SynBinding( + None, + SynBindingKind.Normal, + false, + false, + attrs, + (match xmlDoc with + | Some x -> x + | None -> PreXmlDoc.Empty), + SynValData.SynValData( + Some memberFlag, + SynValInfo([], SynArgInfo(SynAttributes.Empty, false, None)) (*SynValInfo.Empty*) , + None + ), + SynPat.CreateLongIdent( + LongIdentWithDots.CreateString( + this + + "." + + name + ), + [ argsPat ] + ), + None, + expr, + Range.Zero, + DebugPointAtBinding.NoneAtInvisible, + { + LetKeyword = Some Range.Zero + EqualsRange = Some Range.Zero + } + ) + |> fun x -> SynMemberDefn.Member(x, Range.Zero) + +let createMember'' xmlDoc = createMember' xmlDoc "_" + +let createMember = createMember' None "_" diff --git a/Pulumi.FSharp.Myriad/Modules.fs b/src/Pulumi.FSharp.Myriad/Modules.fs similarity index 75% rename from Pulumi.FSharp.Myriad/Modules.fs rename to src/Pulumi.FSharp.Myriad/Modules.fs index 3ba7395..e8670fe 100644 --- a/Pulumi.FSharp.Myriad/Modules.fs +++ b/src/Pulumi.FSharp.Myriad/Modules.fs @@ -11,41 +11,44 @@ open AstBuilder open Debug open Core +let inline equalsCI (str1) (str2) = String.Equals(str1, str2, StringComparison.OrdinalIgnoreCase) + let rec createModule name openNamespace types = match name |> Option.map (String.split '.') with | None -> Module.module'(openNamespace, [ Module.open'("Pulumi." + openNamespace) - yield! types ]) - | Some [| name |] -> let openNamespaces = - match name, String.split '.' openNamespace |> List.ofArray with - // Kubernetes is the only provider, which overrides empty namespace with "Provider" - | "Inputs", [ "Kubernetes"; "Provider" ] -> - [ Module.open'("Pulumi.Kubernetes.Types.Inputs.Provider") ] - | "Inputs", "Kubernetes" :: _ -> - [] - | name , "Kubernetes" :: tail -> - let sub = tail |> String.concat "." - let mn types = Module.open'("Pulumi." + "Kubernetes" + types + sub + "." + name) - [ mn ".Types.Inputs." - mn "." ] - | name, _ -> [ Module.open'("Pulumi." + openNamespace + "." + name) ] - - Module.module'(name, [ - yield! openNamespaces - - yield! types - ]) - | Some [| name; subname |] -> Module.module'(name, [ - createModule (Some subname) (openNamespace + "." + name) types - ]) + | Some [| name |] -> + let openNamespaces = + match name, String.split '.' openNamespace |> List.ofArray with + // Kubernetes is the only provider, which overrides empty namespace with "Provider" + | "Inputs", [ "Kubernetes"; "Provider" ] -> + [ Module.open'("Pulumi.Kubernetes.Types.Inputs.Provider") ] + | "Inputs", "Kubernetes" :: _ -> + [] + | name , "Kubernetes" :: tail -> + let sub = tail |> String.concat "." + let mn types = Module.open'("Pulumi." + "Kubernetes" + types + sub + "." + name) + [ + mn ".Types.Inputs." + mn "." + ] + | name, _ -> [ Module.open'("Pulumi." + openNamespace + "." + name) ] + + Module.module'(name, [ + yield! openNamespaces + yield! types + ]) + | Some [| name; subname |] -> + Module.module'(name, [ + createModule (Some subname) (openNamespace + "." + name) types + ]) | _ -> failwith "Too many dots" let createModule' name openNamespaces types = Module.module'(name, [ yield! openNamespaces |> List.map (fun openNamespace -> Module.open'("Pulumi." + openNamespace)) - yield! types ]) @@ -101,8 +104,7 @@ let private (|PTUnionMany|_|) = let private (|PTRef|_|) = function - | Property("type") (JsonValue.String("string")) & - Property("$ref") (JsonValue.String(StartsWith("#/types/") typeQualified)) + | Property("type") (JsonValue.String("string")) & Property("$ref") (JsonValue.String(StartsWith("#/types/") typeQualified)) | Property("$ref") (JsonValue.String(StartsWith("#/types/") typeQualified)) -> Some typeQualified | _ -> None @@ -209,38 +211,44 @@ let private createPTypes isType allTypes properties = let private missingStatusTypes = [| - "VolumeAttachment" - "PodDisruptionBudget" - "Ingress" - "FlowSchema" - "PriorityLevelConfiguration" + "APIService" + "CertificateSigningRequest" + "CronJob" + "CustomResourceDefinition" "DaemonSet" "Deployment" - "ReplicaSet" + "FlowSchema" + "HorizontalPodAutoscaler" + "Ingress" + "Job" "Namespace" + "NetworkPolicy" "Node" "PersistentVolume" "PersistentVolumeClaim" + "PersistentVolumeClaimPatch" "Pod" + "PodDisruptionBudget" + "PodScheduling" + "PodSchedulingContext" + "PriorityLevelConfiguration" + "ReplicaSet" "ReplicationController" + "ResourceClaim" "ResourceQuota" "Service" - "CertificateSigningRequest" - "CronJob" - "Job" - "HorizontalPodAutoscaler" + "ServiceCIDR" "StatefulSet" - "APIService" - "CustomResourceDefinition" - "PersistentVolumeClaimPatch" - "NetworkPolicy" - "PodSchedulingContext" - "ResourceClaim" - "PodScheduling" + "StorageVersionMigration" "ValidatingAdmissionPolicy" + "VolumeAttachment" |] |> Set.ofArray let createTypes (schema : JsonValue) = + + let pulumiProviderName = + schema["name"].AsString() + let typesJson = match schema.TryGetProperty("types") with | Some types -> types.Properties() @@ -251,7 +259,16 @@ let createTypes (schema : JsonValue) = let allAvailableTypes = typesJson |> Array.map fst - + + let resourcesJson = + schema["resources"].Properties() |> + // Faking Provider to be in the root namespace + Array.append [| $"{pulumiProviderName}:index:Provider", schema["provider"] |] + + let resourceTypes = Map.ofArray resourcesJson + let allResources = + resourcesJson |> Array.map fst + let getPropertiesValues = function | JsonValue.Record(Property("inputProperties") (JsonValue.Record(jv))) @@ -269,44 +286,40 @@ let createTypes (schema : JsonValue) = let rec getRefType = function - | PTRef t when Map.containsKey t allTypes -> Some [t] - + | PTRef t when Array.exists (equalsCI t) allAvailableTypes -> Some [t] + | PTRef t when Array.exists (equalsCI t) allResources -> Some [t] | PTMap t - | PTArray t -> getRefType t - - | PTUnion (a, b) (*PTUnion typeTuple*) -> //typeTuple |> tupleMap getRefType |> optionApply (@) - //typeTuple |> tupleMap getRefType |> lift2 (@) - //typeTuple |> - //tupleMap getRefType ||> - //(fun x y -> List.append x <*> y) - List.append (getRefType a) <*> (getRefType b) - - | PTMap t -> getRefType t - + | PTArray t -> getRefType t + | PTUnion (a, b) -> + List.append (getRefType a) <*> (getRefType b) + | PTMap t -> getRefType t | PTUnionMany _ | PTBase _ - | PTJson -> None + | PTJson -> None | x -> failwith $"Pattern not matched {x}" let rec getAllNestedTypes refTypes resourceOrType = + + let (|ExistsInCI|_|) collection input = + if Seq.exists (equalsCI input) collection then Some () else None + + let (|GetCI|_|) (map: Map<_, JsonValue>) (key: string) = + Map.tryPick (fun k v -> if equalsCI k key then Some v else None) map + getPropertiesValues resourceOrType |> Array.choose getRefType |> - List.concat |> - (function - | [] -> refTypes - | a -> a |> List.collect (fun refType -> match List.exists ((=)refType) refTypes with - | true -> refTypes - | false -> allTypes[refType] |> - getAllNestedTypes (refType :: refTypes))) - - let pulumiProviderName = - schema["name"].AsString() - - let resourcesJson = - schema["resources"].Properties() |> - // Faking Provider to be in the root namespace - Array.append [| $"{pulumiProviderName}:index:Provider", schema["provider"] |] - + List.concat + |> (function + | [] -> refTypes + | a -> a |> List.collect (fun refType -> + match refType with + | ExistsInCI refTypes -> refTypes + | GetCI allTypes typeJson + | GetCI resourceTypes typeJson -> typeJson |> getAllNestedTypes (refType :: refTypes) + | _ -> failwith "Referenced type does not exist in the Pulumi schema resources or types" + ) + ) + let allNestedTypes = resourcesJson |> Array.map (snd >> getAllNestedTypes []) |> @@ -348,14 +361,14 @@ let createTypes (schema : JsonValue) = // Docker schema has inconsistency of case in resource type and name for some resources let resourceTypeAndNameComparison = match pulumiProviderName with - | "docker" -> StringComparison.OrdinalIgnoreCase + | "docker" | "aws" -> StringComparison.OrdinalIgnoreCase | _ -> StringComparison.Ordinal - subNamespaceOrName |> - Option.bind (function - | name when name.Equals(t.ResourceType.Value, resourceTypeAndNameComparison) -> None - | _ -> namespace' + "/" + t.SubNamespace.Value |> Some) |> - Option.defaultValue namespace' + subNamespaceOrName + |> Option.bind (function + | name when name.Equals(t.ResourceType.Value, resourceTypeAndNameComparison) -> None + | _ -> namespace' + "/" + t.SubNamespace.Value |> Some) + |> Option.defaultValue namespace' let namespacesJson = match schema["language"].["csharp"].TryGetProperty("namespaces") with @@ -372,6 +385,9 @@ let createTypes (schema : JsonValue) = Map.add "remote" (Some("Remote")) let create allTypes (jsonValue : JsonValue) (propertyName : string) typeName isType = + + let isComponent = if not isType then jsonValue.TryGetProperty "isComponent" |> Option.isSome else false + let properties = match jsonValue.TryGetProperty(propertyName) with | Some ip -> ip.Properties() @@ -408,7 +424,7 @@ let createTypes (schema : JsonValue) = [||] else [| - createBuilderClass isType typeName pTypes + createBuilderClass isType isComponent typeName pTypes createBuilderInstance description typeName pTypes |] @@ -437,28 +453,39 @@ let createTypes (schema : JsonValue) = let filterKubernetesProblematicTypes types = types |> - Array.filter (fun (bt, _) -> match bt with - | Type t -> not (t.ResourceType.Value = "FetchOpts" && - t.ResourceProviderNamespace.Value = "helm.sh") - | Resource r -> not (r.ResourceType.Value = "Chart" && - r.ResourceProviderNamespace.Value = "helm.sh")) + Array.filter (fun (bt, _) -> + match bt with + | Type t -> not (t.ResourceType.Value = "FetchOpts" && t.ResourceProviderNamespace.Value = "helm.sh") + | Resource r -> not (r.ResourceType.Value = "Chart" && r.ResourceProviderNamespace.Value = "helm.sh")) let filterAzureNativeProblematicTypes types = types |> - Array.filter (fun (bt, _) -> match bt with - | Type t -> not (t.ResourceType.Value = "ApplicationCondition" && - t.ResourceProviderNamespace.Value = "security") - | _ -> true) + Array.filter (fun (bt, _) -> + match bt with + | Type t -> not (t.ResourceType.Value = "ApplicationCondition" && t.ResourceProviderNamespace.Value = "security") + | _ -> true) + let filterAwsProblematicTypes types = + types |> + Array.filter (fun (bt, _) -> + match bt with + // this seems to be a nodejs-only mixin? CallbackFunctionArgs does not exist in the pulumi .net sdk + | Resource r -> + not (r.ResourceType.Value = "CallbackFunction" && r.ResourceProviderNamespace.Value = "lambda") + | Type t -> + not (t.ResourceType.Value = "CodePathOptions" && t.ResourceProviderNamespace.Value = "lambda")) + let createBuildersParallelFiltered allTypes typesOrResources = Array.groupBy (fst >> getProvider) typesOrResources |> filters |> Map.ofArray |> - Map.map (fun _ typesOrResources -> typesOrResources |> - debugFilterTypes |> - filterKubernetesProblematicTypes |> - filterAzureNativeProblematicTypes |> - Array.Parallel.collect (createBuilders allTypes)) + Map.map (fun _ typesOrResources -> + typesOrResources |> + debugFilterTypes |> + filterKubernetesProblematicTypes |> + filterAzureNativeProblematicTypes |> + filterAwsProblematicTypes |> + Array.Parallel.collect (createBuilders allTypes)) let typeBuilders = createBuildersParallelFiltered allAvailableTypes types @@ -472,8 +499,17 @@ let createTypes (schema : JsonValue) = | _ -> pulumiProviderName |> toPascalCase let folder modules resourceProvider resourceBuilders = - let resourceProviderNamespace = - namespaces[resourceProvider] + + let ns :: subns = + match pulumiProviderName with + // GCP is the only provider that seems to use inconsistent namespacing/resource provider namnes + // ex: `gcp:privilegedaccessmanager/entitlement` belongs to `PrivilegedAccessManager` + | "gcp" -> + String.split '/' resourceProvider + |> Array.toList + | _ -> [resourceProvider] + + let resourceProviderNamespace = namespaces[ns] let openNamespace = resourceProviderNamespace |> @@ -482,9 +518,12 @@ let createTypes (schema : JsonValue) = // Kubernetes is the only provider which overrides empty namespace with "Provider" match pulumiProviderName with | "kubernetes" -> namespaces[""] - | _ -> None) |> - Option.map (fun rpn -> $"{cloudProviderNamespace}.{rpn}") |> - Option.defaultValue cloudProviderNamespace + | _ -> None) + |> Option.map (fun rpn -> + match subns with + | [] -> $"{cloudProviderNamespace}.{rpn}" + | subns -> $"""{cloudProviderNamespace}.{String.Join(".", subns)}.{rpn}""") + |> Option.defaultValue cloudProviderNamespace let typesModule = typeBuilders |> @@ -506,4 +545,4 @@ let createTypes (schema : JsonValue) = Map.fold folder List.empty |> List.partition (function | { ResourceProviderNamespace = None } -> true - | _ -> false) \ No newline at end of file + | _ -> false) diff --git a/src/Pulumi.FSharp.Myriad/Namespace.fs b/src/Pulumi.FSharp.Myriad/Namespace.fs new file mode 100644 index 0000000..862c1e1 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Namespace.fs @@ -0,0 +1,14 @@ +module AstNamespace + +open AstHelpers + +let createNamespace module' = + Namespace.namespace' ( + "Pulumi.FSharp", + [ + Module.open' ("Pulumi.FSharp") + Module.open' ("Pulumi") + + module' + ] + ) diff --git a/src/Pulumi.FSharp.Myriad/Operations.fs b/src/Pulumi.FSharp.Myriad/Operations.fs new file mode 100644 index 0000000..b19a393 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Operations.fs @@ -0,0 +1,445 @@ +module AstOperations + +open FSharp.Compiler.Syntax +open FSharp.Compiler.Xml +open AstAttribute +open AstHelpers +open AstMember +open Myriad.Core.AstExtensions +open Myriad.Core.Ast +open Core + +let private createPatternTyped name args (typeName: string) = + SynPat.CreateTyped( + SynPat.CreateLongIdent(LongIdentWithDots.CreateString(name), args), + SynType.CreateLongIdent(typeName) + ) + +let private createTuple items withParen = + if withParen then + SynPat.CreateParen(SynPat.CreateTuple(items)) + else + SynPat.CreateTuple(items) + +let private argsPattern = createPattern "args" [] + +let private crosPattern = createPattern "cros" [] + +let private nPattern = createPattern "n" [] + +let private namePattern = createPattern "name" [] + +let createPatternFromCache nameVarName = + match nameVarName with + | "n" -> nPattern + | "name" -> namePattern + | _ -> createPattern nameVarName [] + +let argsTuple' isResource nameVarName withParen = + let nvn = + match nameVarName with + | null -> SynPat.CreateWild + | _ -> createPatternFromCache nameVarName + + createTuple + [ + nvn + argsPattern + if isResource then + crosPattern + ] + withParen + +let argsTupleResource withParen = + createTuple + [ + namePattern + argsPattern + crosPattern + ] + withParen + +let argsTupleType withParen = + createTuple + [ + SynPat.CreateWild + argsPattern + ] + withParen + +let private createOperation'' + isResource + (xmlDoc: string list) + nameVarName + name + coName + argName + hasAttribute + typ + = + let attributes = + if hasAttribute then + [ createAttributeWithArg "CustomOperation" coName ] + else + [] + + let patterns = + createTuple + [ + argsTuple' isResource nameVarName true + match typ with + | None -> createPattern argName [] + | Some typ -> createPatternTyped argName [] typ + ] + true + + let doc = + PreXmlDoc.Create(xmlDoc) + |> Some + + createMember'' doc name patterns attributes + +let createNameOperation newNameExpr = + createOperation'' + true + [ "Pulumi logical resource name" ] + null + "Name" + "name" + "newName" + true + None + newNameExpr + +let private listCons = + Expr.appTuple ( + "List.Cons", + [ + "apply" + "args" + ] + ) + +let private nReturnTuple = Expr.tuple (Expr.ident ("n"), listCons) + +let private nameReturnTuple = Expr.tuple (Expr.ident ("name"), listCons) + +let private argsIdent = Expr.ident ("args") + +let private inputIdent = Expr.ident ("input") + +let private ioIdent = Expr.ident ("io") + +let private inputListIdent = Expr.ident ("inputList") + +let private inputMapIdent = Expr.ident ("inputMap") + +let private inputJson = Expr.longIdent ("Pulumi.InputJson.op_Implicit") + +let private resourceNameIdent = Expr.ident ("resourceName") + +let private resourceTypeIdent = Expr.ident ("resourceType") + +let private compose = Expr.paren (Expr.ident ("op_ComposeRight")) + +let private inputListFromSeqOf (expr: SynExpr) = + Expr.paren ( + Expr.app ( + compose, + [ + Expr.paren (Expr.app (Expr.longIdent ("Seq.map"), expr)) + inputListIdent + ] + ) + ) + +let private inputMapFromMapOf (expr: SynExpr) = + let mapSelector = + Expr.paren ( + Expr.lambda ( + [ + SimplePat.id ("k") + SimplePat.id ("v") + ], + Expr.tuple (Expr.ident ("k"), Expr.app (expr, Expr.ident ("v"))) + ) + ) + + Expr.paren ( + Expr.app ( + compose, + [ + Expr.paren (Expr.app (Expr.longIdent ("Seq.map"), mapSelector)) + inputMapIdent + ] + ) + ) + +let private inputMapFromMapOfInput = inputMapFromMapOf inputIdent + +let private inputMapFromMapOfOutput = inputMapFromMapOf ioIdent + +let private inputListFromSeq = inputListFromSeqOf inputIdent + +let private inputListFromOutputSeq = inputListFromSeqOf ioIdent + +let private inputListFromItemOf (expr: SynExpr) = + Expr.paren ( + Expr.app ( + compose, + Expr.app ( + Expr.paren ( + Expr.app ( + compose, + [ + expr + Expr.longIdent ("Seq.singleton") + ] + ) + ), + inputListIdent + ) + ) + ) + +let private inputListFromItem = inputListFromItemOf inputIdent + +let private inputListFromOutput = inputListFromItemOf ioIdent + +let private inputUnion1Of2 = Expr.ident ("inputUnion1Of2") + +let private inputUnion2Of2 = Expr.ident ("inputUnion2Of2") + +let private idIdent = Expr.ident ("id") + +type PType = + | PArray of PType + | PUnion of PType * PType + | PString + | PInteger + | PFloat + | PBoolean + | PMap of PType + | PJson + | PAssetOrArchive + | PArchive + | PAny + | PRef of string + +type Deprecation = + | Current + | Deprecated of string + +type PTypeDefinition = { + Name: string + Type: PType + Description: string + Deprecation: Deprecation + CanGenerateYield: bool + IsResource: bool + OperationName: string +} + +// This should be the same as the member arg (currently "n") +let private returnTupleCache argsType pType opName setRight = + let set = Expr.set ($"args.{pType.Name}", setRight) + + let lambdaExpr = + Expr.sequential ( + [ + set + Expr.ident ("args") + ] + ) + + let lambda = Expr.lambda ([ SimplePat.typed ("args", argsType) ], lambdaExpr) + + let consArg = Expr.paren (Expr.tuple (Expr.paren (lambda), Expr.ident ("args"))) + + let cons = Expr.app (Expr.longIdent ("List.Cons"), consArg) + + match pType.IsResource with + | false -> Expr.tuple (Expr.ident ("n"), cons) + | true -> Expr.tuple (Expr.ident ("name"), cons, Expr.ident ("cros")) + +let createOperationsFor' argsType pType = + let setRights, argType = + match pType with + | { PTypeDefinition.Type = PString } + | { Type = PInteger } + | { Type = PFloat } + | { Type = PBoolean } -> + [ + inputIdent + ioIdent + ], + None + | { Type = PArray _ } -> + [ + inputListIdent + inputListFromSeq + inputListFromOutputSeq + inputListFromItem + inputListFromOutput + ], + None + | { Type = PUnion _ } -> + [ + idIdent + inputUnion1Of2 + inputUnion2Of2 + ], + None + | { Type = PJson } -> [ inputJson ], Some "string" + | { Type = PMap _ } -> + [ + idIdent + inputMapIdent + inputMapFromMapOfInput + inputMapFromMapOfOutput + ], + None + | { Type = PRef _ } + | { Type = PArchive } + | { Type = PAny } + | { Type = PAssetOrArchive } -> [ inputIdent ], None + + let snakeCaseName = + if + pType.Name = "Name" + && pType.IsResource + then + "resourceName" + else + toCamelCase pType.Name + + let argName = + match snakeCaseName with + | "fixed" + | "input" + | "args" -> + snakeCaseName + + "\'" + | "type" -> "resourceType" + | _ -> snakeCaseName + + let operationName = + match pType.Name with + | "Name" when pType.IsResource -> resourceNameIdent + | "Type" when pType.IsResource -> resourceTypeIdent + | _ -> Expr.ident (argName) + + let nameArgName = + if pType.IsResource then "name" + elif pType.OperationName = "n" then "nx" + else "n" + + let memberName = + pType.OperationName + |> toPascalCase + + let doc = + String.split '\n' pType.Description + |> Array.filter ( + (=) "" + >> not + ) + |> List.ofArray + + let returnTupleCache' = returnTupleCache argsType pType operationName + + let argNameExpr = Expr.ident (argName) + + setRights + |> List.map ( + (fun sr -> Expr.app (sr, argNameExpr)) + >> returnTupleCache' + ) + |> List.mapi (fun i e -> + createOperation'' + pType.IsResource + doc + nameArgName + memberName + pType.OperationName + argName + (i = 0) + argType + e + ) + +type internal ResourceOptionsKind = + | ResourceOptions + | CustomResourceOptions + | ComponentResourceOptions + +let internal croOperation + operationName + resourceOptionsKind + description + argumentName + (setAssignmentExpression: SynExpr) + isListAdd + withAttribute + = + let attributes = [ + if withAttribute then + createAttributeWithArg + "CustomOperation" + (operationName + |> toCamelCase) + ] + + let patterns = + createTuple + [ + argsTupleResource true + createPattern argumentName [] + ] + true + + let doc = + PreXmlDoc.Create([ description ]) + |> Some + + let updateCrosExpression setAssignmentExpression = + let lambdaExpression = + Expr.sequential ( + [ + if not isListAdd then + Expr.set ($"cros.{operationName}", setAssignmentExpression) + else + Expr.appTuple ( + $"cros.{operationName}.AddRange", + [ setAssignmentExpression ] + ) + Expr.ident ("cros") + ] + ) + + let listConsLambdaFirstExpression = + Expr.lambda ( + match resourceOptionsKind with + | ResourceOptions -> [ SimplePat.hashTyped ("cros", "ResourceOptions") ] + | CustomResourceOptions -> [ SimplePat.typed ("cros", "CustomResourceOptions") ] + | ComponentResourceOptions -> [ + SimplePat.typed ("cros", "ComponentResourceOptions") + ] + , lambdaExpression + ) + + let listConsExpressions = + Expr.paren ( + Expr.tuple (Expr.paren (listConsLambdaFirstExpression), Expr.ident ("cros")) + ) + + Expr.app (Expr.longIdent ("List.Cons"), listConsExpressions) + + let expression = + Expr.tuple ( + Expr.ident ("name"), + Expr.ident ("args"), + updateCrosExpression setAssignmentExpression + ) + + createMember'' doc operationName patterns attributes expression diff --git a/src/Pulumi.FSharp.Myriad/Pulumi.FSharp.Myriad.fsproj b/src/Pulumi.FSharp.Myriad/Pulumi.FSharp.Myriad.fsproj new file mode 100644 index 0000000..ca70500 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Pulumi.FSharp.Myriad.fsproj @@ -0,0 +1,41 @@ + + + + net6.0 + preview + NU1605,NU1608 + true + Pulumi.FSharp.Myriad + + + + true + %(Identity) + true + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Pulumi.FSharp.Myriad/Run.fs b/src/Pulumi.FSharp.Myriad/Run.fs new file mode 100644 index 0000000..f534ec5 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Run.fs @@ -0,0 +1,8 @@ +module AstRun + +open AstMember +open AstOperations + +let createRunResource = createMember "Run" (argsTupleResource true) [] + +let createRunType = createMember "Run" (argsTupleType true) [] diff --git a/src/Pulumi.FSharp.Myriad/Schema.fs b/src/Pulumi.FSharp.Myriad/Schema.fs new file mode 100644 index 0000000..46a8e8d --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Schema.fs @@ -0,0 +1,29 @@ +module Schema + +open System +open FSharp.Data +open System.IO +open Fantomas + +let private getSchemaFromFileCacheOrDownload provider version schemaUrl = + match FileInfo($"{provider}.{version}.json") with + | fi when fi.Exists -> fi.OpenText().ReadToEnd() + | fi -> + let json = Http.RequestString(schemaUrl) +#if DEBUG + use fi = fi.CreateText() in + + json + |> fi.Write +#endif + json + +let private loadSchema' version provider = + $"https://raw.githubusercontent.com/pulumi/pulumi-{provider}/v{version}" + + $"/provider/cmd/pulumi-resource-{provider}/schema.json" + |> getSchemaFromFileCacheOrDownload provider version + |> JsonValue.Parse + +let loadSchema provider version = + String.map Char.ToLower provider + |> loadSchema' version diff --git a/src/Pulumi.FSharp.Myriad/Yield.fs b/src/Pulumi.FSharp.Myriad/Yield.fs new file mode 100644 index 0000000..20906d2 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/Yield.fs @@ -0,0 +1,21 @@ +module AstYield + +open AstMember +open FSharp.Compiler.Syntax +open Myriad.Core.Ast +open Myriad.Core.AstExtensions + +let createYield' isType (arg: SynPat) (args: SynExpr) (cros: SynExpr) = + [ + SynExpr.CreateNull + args + if not isType then + cros + ] + |> SynExpr.CreateTuple + |> createMember "Yield" arg [] + +let createYield isType = + let typedWildcardUnit = SynPat.CreateTyped(SynPat.CreateWild, SynType.CreateUnit) + + createYield' isType typedWildcardUnit diff --git a/Pulumi.FSharp.Myriad/build/Pulumi.FSharp.Myriad.InTest.props b/src/Pulumi.FSharp.Myriad/build/Pulumi.FSharp.Myriad.InTest.props similarity index 100% rename from Pulumi.FSharp.Myriad/build/Pulumi.FSharp.Myriad.InTest.props rename to src/Pulumi.FSharp.Myriad/build/Pulumi.FSharp.Myriad.InTest.props diff --git a/Pulumi.FSharp.Myriad/build/Pulumi.FSharp.Myriad.props b/src/Pulumi.FSharp.Myriad/build/Pulumi.FSharp.Myriad.props similarity index 100% rename from Pulumi.FSharp.Myriad/build/Pulumi.FSharp.Myriad.props rename to src/Pulumi.FSharp.Myriad/build/Pulumi.FSharp.Myriad.props diff --git a/src/Pulumi.FSharp.Myriad/myriad.toml b/src/Pulumi.FSharp.Myriad/myriad.toml new file mode 100644 index 0000000..e69de29 diff --git a/src/Pulumi.FSharp.Myriad/paket.references b/src/Pulumi.FSharp.Myriad/paket.references new file mode 100644 index 0000000..1bd8fa4 --- /dev/null +++ b/src/Pulumi.FSharp.Myriad/paket.references @@ -0,0 +1,5 @@ +group Myriad + FSharp.Data + FSharp.Text.RegexProvider + Myriad.Sdk + Paket.Core \ No newline at end of file