Reorganize source code in preparation to move into aspnet/AspNetCore
Prior to reorganization, this source code was found in d745b8c161
This commit is contained in:
commit
401fd68985
|
|
@ -1,17 +0,0 @@
|
|||
init:
|
||||
- git config --global core.autocrlf true
|
||||
branches:
|
||||
only:
|
||||
- dev
|
||||
- /^release\/.*$/
|
||||
- /^(.*\/)?ci-.*$/
|
||||
build_script:
|
||||
- ps: .\run.ps1 default-build
|
||||
clone_depth: 1
|
||||
environment:
|
||||
global:
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
test: 'off'
|
||||
deploy: 'off'
|
||||
os: Visual Studio 2017
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
# EditorConfig is awesome:http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.cs]
|
||||
indent_size = 4
|
||||
dotnet_sort_system_directives_first = true:warning
|
||||
|
||||
# Xml files
|
||||
[*.{csproj,config,props,targets,ruleset,config,resx,xml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.{json, yml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.{ps1,sh}]
|
||||
indent_size = 4
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
*.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
|
||||
|
||||
*.jpg binary
|
||||
*.png binary
|
||||
*.gif binary
|
||||
|
||||
*.cs text=auto diff=csharp
|
||||
*.vb text=auto
|
||||
*.resx text=auto
|
||||
*.c text=auto
|
||||
*.cpp text=auto
|
||||
*.cxx text=auto
|
||||
*.h text=auto
|
||||
*.hxx text=auto
|
||||
*.py text=auto
|
||||
*.rb text=auto
|
||||
*.java text=auto
|
||||
*.html text=auto
|
||||
*.htm text=auto
|
||||
*.css text=auto
|
||||
*.scss text=auto
|
||||
*.sass text=auto
|
||||
*.less text=auto
|
||||
*.js text=auto
|
||||
*.lisp text=auto
|
||||
*.clj text=auto
|
||||
*.sql text=auto
|
||||
*.php text=auto
|
||||
*.lua text=auto
|
||||
*.m text=auto
|
||||
*.asm text=auto
|
||||
*.erl text=auto
|
||||
*.fs text=auto
|
||||
*.fsx text=auto
|
||||
*.hs text=auto
|
||||
|
||||
*.csproj text=auto
|
||||
*.vbproj text=auto
|
||||
*.fsproj text=auto
|
||||
*.dbproj text=auto
|
||||
*.sln text=auto eol=crlf
|
||||
|
||||
*.sh eol=lf
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
[Oo]bj/
|
||||
[Bb]in/
|
||||
TestResults/
|
||||
.nuget/
|
||||
_ReSharper.*/
|
||||
packages/
|
||||
artifacts/
|
||||
PublishProfiles/
|
||||
*.user
|
||||
*.suo
|
||||
*.cache
|
||||
*.docstates
|
||||
_ReSharper.*
|
||||
nuget.exe
|
||||
*net45.csproj
|
||||
*net451.csproj
|
||||
*k10.csproj
|
||||
*.psess
|
||||
*.vsp
|
||||
*.pidb
|
||||
*.userprefs
|
||||
*DS_Store
|
||||
*.ncrunchsolution
|
||||
*.*sdf
|
||||
*.ipch
|
||||
*.sln.ide
|
||||
project.lock.json
|
||||
.testPublish/
|
||||
.build/
|
||||
/.vs/
|
||||
.vscode/
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
.idea/
|
||||
.dotnet/
|
||||
global.json
|
||||
*.binlog
|
||||
27
.travis.yml
27
.travis.yml
|
|
@ -1,27 +0,0 @@
|
|||
language: csharp
|
||||
sudo: false
|
||||
dist: trusty
|
||||
env:
|
||||
global:
|
||||
- DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
- DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||
mono: none
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
osx_image: xcode8.2
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libunwind8
|
||||
branches:
|
||||
only:
|
||||
- dev
|
||||
- /^release\/.*$/
|
||||
- /^(.*\/)?ci-.*$/
|
||||
before_install:
|
||||
- if test "$TRAVIS_OS_NAME" == "osx"; then brew update; brew install openssl; ln -s
|
||||
/usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/; ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
|
||||
/usr/local/lib/; fi
|
||||
script:
|
||||
- ./build.sh
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
trigger:
|
||||
- master
|
||||
- release/*
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: buildtools
|
||||
type: git
|
||||
name: aspnet-BuildTools
|
||||
ref: refs/heads/release/2.2
|
||||
|
||||
phases:
|
||||
- template: .vsts-pipelines/templates/project-ci.yml@buildtools
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
trigger:
|
||||
- master
|
||||
- release/*
|
||||
|
||||
# See https://github.com/aspnet/BuildTools
|
||||
resources:
|
||||
repositories:
|
||||
- repository: buildtools
|
||||
type: github
|
||||
endpoint: DotNet-Bot GitHub Connection
|
||||
name: aspnet/BuildTools
|
||||
ref: refs/heads/release/2.2
|
||||
|
||||
phases:
|
||||
- template: .vsts-pipelines/templates/project-ci.yml@buildtools
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
Contributing
|
||||
======
|
||||
|
||||
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo.
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<Project>
|
||||
<Import
|
||||
Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))\AspNetCoreSettings.props"
|
||||
Condition=" '$(CI)' != 'true' AND '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), AspNetCoreSettings.props))' != '' " />
|
||||
|
||||
<Import Project="version.props" />
|
||||
<Import Project="build\dependencies.props" />
|
||||
<Import Project="build\sources.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<Product>Microsoft .NET</Product>
|
||||
<RepositoryUrl>https://github.com/aspnet/DotNetTools</RepositoryUrl>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
|
||||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)build\Key.snk</AssemblyOriginatorKeyFile>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
|
||||
<!-- Binary compatiblity is not a goal for command-line tools. -->
|
||||
<EnableApiCheck>false</EnableApiCheck>
|
||||
<BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)obj\$(MSBuildProjectName)\</BaseIntermediateOutputPath>
|
||||
<BaseOutputPath>$(MSBuildThisFileDirectory)bin\$(MSBuildProjectName)\</BaseOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.1' ">$(MicrosoftNETCoreApp21PackageVersion)</RuntimeFrameworkVersion>
|
||||
<RuntimeFrameworkVersion Condition=" '$(TargetFramework)' == 'netcoreapp2.2' ">$(MicrosoftNETCoreApp22PackageVersion)</RuntimeFrameworkVersion>
|
||||
<NETStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard2.0' ">$(NETStandardLibrary20PackageVersion)</NETStandardImplicitPackageVersion>
|
||||
<!-- aspnet/BuildTools#662 Don't police what version of NetCoreApp we use -->
|
||||
<NETCoreAppMaximumVersion>99.9</NETCoreAppMaximumVersion>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
206
DotNetTools.sln
206
DotNetTools.sln
|
|
@ -1,206 +0,0 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27120.0
|
||||
MinimumVisualStudioVersion = 15.0.26730.03
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{66517987-2A5A-4330-B130-207039378FD4}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\Directory.Build.props = src\Directory.Build.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-watch", "src\dotnet-watch\dotnet-watch.csproj", "{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8321E0D1-9A47-4D2F-AED8-3AE636D44E35}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.appveyor.yml = .appveyor.yml
|
||||
.editorconfig = .editorconfig
|
||||
.gitattributes = .gitattributes
|
||||
.gitignore = .gitignore
|
||||
.travis.yml = .travis.yml
|
||||
build.cmd = build.cmd
|
||||
build.ps1 = build.ps1
|
||||
build.sh = build.sh
|
||||
CONTRIBUTING.md = CONTRIBUTING.md
|
||||
build\dependencies.props = build\dependencies.props
|
||||
Directory.Build.props = Directory.Build.props
|
||||
Directory.Build.targets = Directory.Build.targets
|
||||
LICENSE.txt = LICENSE.txt
|
||||
NuGet.config = NuGet.config
|
||||
NuGetPackageVerifier.json = NuGetPackageVerifier.json
|
||||
README.md = README.md
|
||||
build\sources.props = build\sources.props
|
||||
version.props = version.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F5B382BC-258F-46E1-AC3D-10E5CCD55134}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
test\Directory.Build.props = test\Directory.Build.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-watch.FunctionalTests", "test\dotnet-watch.FunctionalTests\dotnet-watch.FunctionalTests.csproj", "{16BADE2F-1184-4518-8A70-B68A19D0805B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-user-secrets", "src\dotnet-user-secrets\dotnet-user-secrets.csproj", "{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-user-secrets.Tests", "test\dotnet-user-secrets.Tests\dotnet-user-secrets.Tests.csproj", "{7B331122-83B1-4F08-A119-DC846959844C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-watch.Tests", "test\dotnet-watch.Tests\dotnet-watch.Tests.csproj", "{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-sql-cache", "src\dotnet-sql-cache\dotnet-sql-cache.csproj", "{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-dev-certs", "src\dotnet-dev-certs\dotnet-dev-certs.csproj", "{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.SecretManager", "tooling\Microsoft.VisualStudio.SecretManager\Microsoft.VisualStudio.SecretManager.csproj", "{5E117F2E-7152-447F-BF47-59F759EEF3A7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tooling", "tooling", "{62826851-7D74-4F1E-B7D1-12553B789CD8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.VisualStudio.SecretManager.TestExtension", "tooling\Microsoft.VisualStudio.SecretManager.TestExtension\Microsoft.VisualStudio.SecretManager.TestExtension.csproj", "{965F8820-F809-4081-9090-1AEC903F291B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.DeveloperCertificates.XPlat", "src\Microsoft.AspNetCore.DeveloperCertificates.XPlat\Microsoft.AspNetCore.DeveloperCertificates.XPlat.csproj", "{96E71881-1465-44F5-B4B7-DF9B370FFD02}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.HttpRepl", "src\Microsoft.HttpRepl\Microsoft.HttpRepl.csproj", "{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Repl", "src\Microsoft.Repl\Microsoft.Repl.csproj", "{EE9A6128-3DE2-4206-A5A4-3ED935084590}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Repl.Tests", "test\Microsoft.Repl.Tests\Microsoft.Repl.Tests.csproj", "{59C2B354-3B5E-40EB-A7BC-74583A5707CA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.HttpRepl.Tests", "test\Microsoft.HttpRepl.Tests\Microsoft.HttpRepl.Tests.csproj", "{BE7CC4CD-CD76-4211-B593-CAC84407162A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
DebugNoVSIX|Any CPU = DebugNoVSIX|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
ReleaseNoVSIX|Any CPU = ReleaseNoVSIX|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7B331122-83B1-4F08-A119-DC846959844C}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{5E117F2E-7152-447F-BF47-59F759EEF3A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5E117F2E-7152-447F-BF47-59F759EEF3A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5E117F2E-7152-447F-BF47-59F759EEF3A7}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5E117F2E-7152-447F-BF47-59F759EEF3A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5E117F2E-7152-447F-BF47-59F759EEF3A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5E117F2E-7152-447F-BF47-59F759EEF3A7}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{965F8820-F809-4081-9090-1AEC903F291B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{965F8820-F809-4081-9090-1AEC903F291B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{965F8820-F809-4081-9090-1AEC903F291B}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{965F8820-F809-4081-9090-1AEC903F291B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{965F8820-F809-4081-9090-1AEC903F291B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{965F8820-F809-4081-9090-1AEC903F291B}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{8A8CEABC-AC47-43FF-A5DF-69224F7E1F46} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{16BADE2F-1184-4518-8A70-B68A19D0805B} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
{8730E848-CA0F-4E0A-9A2F-BC22AD0B2C4E} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{7B331122-83B1-4F08-A119-DC846959844C} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
{8A2E6961-6B12-4A8E-8215-3E7301D52EAC} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
{53F3B53D-303A-4DAA-9C38-4F55195FA5B9} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{4FED5119-EE5C-4753-88A4-D61BDEB4D6C8} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{5E117F2E-7152-447F-BF47-59F759EEF3A7} = {62826851-7D74-4F1E-B7D1-12553B789CD8}
|
||||
{965F8820-F809-4081-9090-1AEC903F291B} = {62826851-7D74-4F1E-B7D1-12553B789CD8}
|
||||
{96E71881-1465-44F5-B4B7-DF9B370FFD02} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{4725BEAD-34F0-43C1-BF46-7AB16B4DE81D} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{EE9A6128-3DE2-4206-A5A4-3ED935084590} = {66517987-2A5A-4330-B130-207039378FD4}
|
||||
{59C2B354-3B5E-40EB-A7BC-74583A5707CA} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
{BE7CC4CD-CD76-4211-B593-CAC84407162A} = {F5B382BC-258F-46E1-AC3D-10E5CCD55134}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {57C07F14-2EAC-44FF-A277-B9221B4B2BF7}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
14
LICENSE.txt
14
LICENSE.txt
|
|
@ -1,14 +0,0 @@
|
|||
Copyright (c) .NET Foundation and Contributors
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed
|
||||
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations under the License.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<clear />
|
||||
<!-- Restore sources should be defined in build/sources.props. -->
|
||||
</packageSources>
|
||||
</configuration>
|
||||
40
README.md
40
README.md
|
|
@ -1,40 +0,0 @@
|
|||
DotNetTools
|
||||
===========
|
||||
|
||||
[](https://travis-ci.org/aspnet/DotNetTools/branches)
|
||||
[](https://ci.appveyor.com/project/aspnetci/DotNetTools/branch/dev)
|
||||
|
||||
This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at <https://docs.asp.net>.
|
||||
|
||||
## Projects
|
||||
|
||||
The repository contains command-line tools for ASP.NET Core that are bundled* in the [.NET Core CLI](https://github.com/dotnet/cli).
|
||||
Follow the links below for more details on each tool.
|
||||
|
||||
- [dotnet-watch](src/dotnet-watch/README.md)
|
||||
- [dotnet-user-secrets](src/dotnet-user-secrets/README.md)
|
||||
- [dotnet-sql-cache](src/dotnet-sql-cache/README.md)
|
||||
- [dotnet-dev-certs](src/dotnet-dev-certs/README.md)
|
||||
|
||||
*\*This applies to .NET Core CLI 2.1.300-preview2 and up. For earlier versions of the CLI, these tools must be installed separately.*
|
||||
|
||||
*For 2.0 CLI and earlier, see <https://github.com/aspnet/DotNetTools/tree/rel/2.0.0/README.md> for details.*
|
||||
|
||||
*For 2.1.300-preview1 CLI, see <https://github.com/aspnet/DotNetTools/tree/2.1.0-preview1-final/README.md> for details.*
|
||||
|
||||
## Usage
|
||||
|
||||
The command line tools can be invoked as a subcommand of `dotnet`.
|
||||
|
||||
```sh
|
||||
dotnet watch
|
||||
dotnet user-secrets
|
||||
dotnet sql-cache
|
||||
dotnet dev-certs
|
||||
```
|
||||
|
||||
Add `--help` to see more details. For example,
|
||||
|
||||
```
|
||||
dotnet watch --help
|
||||
```
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
@ECHO OFF
|
||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE"
|
||||
8
build.sh
8
build.sh
|
|
@ -1,8 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
|
||||
# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs)
|
||||
chmod +x "$DIR/run.sh"; sync
|
||||
"$DIR/run.sh" default-build "$@"
|
||||
BIN
build/Key.snk
BIN
build/Key.snk
Binary file not shown.
|
|
@ -1,9 +0,0 @@
|
|||
<!--
|
||||
Workaround for https://github.com/dotnet/project-system/issues/2129 - VS does not support using MSBuild variables for PackageReference items.
|
||||
Using a variable breaks a bunch of stuff, so this file is injected into the VSIX csproj only when building on commandline.
|
||||
-->
|
||||
<Project ToolsVersion="15.0">
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="$(VisualStudio_NewtonsoftJsonPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<!-- Don't build the VSIX by default in this branch anymore. You can still build the fix by adding /p:BuildVSIX=true. -->
|
||||
<BuildVSIX Condition="'$(BuildVSIX)' ==''">false</BuildVSIX>
|
||||
<RestoreDependsOn Condition="'$(OS)'=='Windows_NT' AND '$(BuildVSIX)' == 'true'">$(RestoreDependsOn);RestoreVSIX</RestoreDependsOn>
|
||||
<PackageDependsOn Condition="'$(OS)'=='Windows_NT' AND '$(BuildVSIX)' == 'true'">$(PackageDependsOn);PackageVSIX</PackageDependsOn>
|
||||
<GetArtifactInfoDependsOn Condition="'$(OS)'=='Windows_NT' AND '$(BuildVSIX)' == 'true'">$(GetArtifactInfoDependsOn);GetVSIXArtifactInfo</GetArtifactInfoDependsOn>
|
||||
<VSIXName>Microsoft.VisualStudio.SecretManager</VSIXName>
|
||||
<VSIXProject>$(RepositoryRoot)tooling\$(VSIXName)\$(VSIXName).csproj</VSIXProject>
|
||||
<VSIXOutputPath>$(BuildDir)$(VSIXName).vsix</VSIXOutputPath>
|
||||
<VSIXManifestOutputPath>$(BuildDir)$(VSIXName).json</VSIXManifestOutputPath>
|
||||
<VSIXSymbolsOutputPath>$(BuildDir)$(VSIXName).pdb</VSIXSymbolsOutputPath>
|
||||
<VSIXArtifactCategory>shipoob</VSIXArtifactCategory>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target
|
||||
Name="GenerateVSIX"
|
||||
DependsOnTargets="RestoreVSIX;PackageVSIX"
|
||||
Condition="'$(OS)'=='Windows_NT'" />
|
||||
|
||||
<Target Name="GetVSIXArtifactInfo">
|
||||
<ItemGroup>
|
||||
<ArtifactInfo Include="$(VSIXOutputPath)">
|
||||
<ArtifactType>VsixPackage</ArtifactType>
|
||||
<Version>$(PackageVersion)</Version>
|
||||
<Category>$(VSIXArtifactCategory)</Category>
|
||||
<PackageId>$(VSIXName)</PackageId>
|
||||
</ArtifactInfo>
|
||||
|
||||
<ArtifactInfo Include="$(VSIXManifestOutputPath)">
|
||||
<ArtifactType>VsixPackageManifestFile</ArtifactType>
|
||||
<Category>$(VSIXArtifactCategory)</Category>
|
||||
<Dependencies>$(VSIXName).vsix</Dependencies>
|
||||
<PackageId>$(VSIXName)</PackageId>
|
||||
</ArtifactInfo>
|
||||
|
||||
<ArtifactInfo Include="$(VSIXSymbolsOutputPath)">
|
||||
<ArtifactType>SymbolsFile</ArtifactType>
|
||||
<Category>$(VSIXArtifactCategory)</Category>
|
||||
<Dependencies>$(VSIXName).vsix</Dependencies>
|
||||
<DebugType>full</DebugType>
|
||||
</ArtifactInfo>
|
||||
|
||||
<FilesToSign Include="$(VSIXOutputPath)" Certificate="$(VsixSigningCertName)" IsContainer="true" />
|
||||
<FilesToSign Include="$(RepositoryRoot)tooling/Microsoft.VisualStudio.SecretManager/bin/$(Configuration)/Microsoft.VisualStudio.SecretManager.dll" Certificate="$(AssemblySigningCertName)" />
|
||||
<FilesToExcludeFromSigning Include="$(VSIXManifestOutputPath)" />
|
||||
<FilesToExcludeFromSigning Include="$(VSIXSymbolsOutputPath)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
VisualStudioMSBuildx86Path is set by the GetToolsets target in KoreBuild if a version of VS matching the requirements in korebuild.json is found.
|
||||
-->
|
||||
<Target Name="RestoreVSIX" DependsOnTargets="GetToolsets">
|
||||
|
||||
<PropertyGroup>
|
||||
<VSIXResponseFilePath>$(LogOutputDir)vsix-restore.rsp</VSIXResponseFilePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<MSBuildArguments Remove="@(MSBuildArguments)" />
|
||||
<MSBuildArguments Include="
|
||||
$(VSIXProject);
|
||||
/t:Restore;
|
||||
/m;
|
||||
/v:m;
|
||||
/p:Configuration=$(Configuration);
|
||||
/p:BuildNumber=$(BuildNumber);
|
||||
/p:PackageReferencePropsPath=$(MSBuildThisFileDirectory)VSIX.props;" />
|
||||
<MSBuildArguments Include="/p:DotNetPackageVersionPropsPath=$(DotNetPackageVersionPropsPath)" Condition="'$(DotNetPackageVersionPropsPath)' != ''" />
|
||||
<MSBuildArguments Include="/p:DotNetRestoreSourcePropsPath=$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''" />
|
||||
</ItemGroup>
|
||||
|
||||
<MakeDir Directories="$(LogOutputDir)" />
|
||||
|
||||
<WriteLinesToFile
|
||||
File="$(VSIXResponseFilePath)"
|
||||
Lines="@(MSBuildArguments)"
|
||||
Overwrite="true" />
|
||||
|
||||
<Exec Command=""$(VisualStudioMSBuildx86Path)" @"$(VSIXResponseFilePath)""
|
||||
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PackageVSIX" DependsOnTargets="GetToolsets">
|
||||
|
||||
<Error Text="Could not find a version of Visual Studio that has the Visual Studio SDK installed. This is required to build the SecretManager VSIX."
|
||||
Condition="'$(VisualStudioMSBuildx86Path)' == ''" />
|
||||
|
||||
<PropertyGroup>
|
||||
<VSIXLogFilePath>$(LogOutputDir)vsix.log</VSIXLogFilePath>
|
||||
<VSIXResponseFilePath>$(LogOutputDir)vsix-build.rsp</VSIXResponseFilePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<MSBuildArguments Remove="@(MSBuildArguments)" />
|
||||
<MSBuildArguments Include="
|
||||
$(VSIXProject);
|
||||
/m;
|
||||
/v:M;
|
||||
/fl;
|
||||
/flp:LogFile=$(VSIXLogFilePath);
|
||||
/p:DeployExtension=false;
|
||||
/p:TargetVSIXContainer=$(VSIXOutputPath);
|
||||
/p:Configuration=$(Configuration);
|
||||
/p:SymbolsPublishDir=$(BuildDir);
|
||||
/p:PackageReferencePropsPath=$(MSBuildThisFileDirectory)VSIX.props;" />
|
||||
</ItemGroup>
|
||||
|
||||
<MakeDir Directories="$(LogOutputDir)" />
|
||||
|
||||
<WriteLinesToFile
|
||||
File="$(VSIXResponseFilePath)"
|
||||
Lines="@(MSBuildArguments)"
|
||||
Overwrite="true" />
|
||||
|
||||
<Exec Command=""$(VisualStudioMSBuildx86Path)" @"$(VSIXResponseFilePath)""
|
||||
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Package Versions">
|
||||
<InternalAspNetCoreSdkPackageVersion>2.2.0-preview2-20181026.4</InternalAspNetCoreSdkPackageVersion>
|
||||
<MicrosoftAspNetCoreCertificatesGenerationSourcesPackageVersion>2.2.0-rtm-35542</MicrosoftAspNetCoreCertificatesGenerationSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreTestingPackageVersion>2.2.0-rtm-35542</MicrosoftAspNetCoreTestingPackageVersion>
|
||||
<MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>2.2.0-rtm-35542</MicrosoftExtensionsCommandLineUtilsSourcesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationUserSecretsPackageVersion>2.2.0-rtm-35545</MicrosoftExtensionsConfigurationUserSecretsPackageVersion>
|
||||
<MicrosoftExtensionsProcessSourcesPackageVersion>2.2.0-rtm-35542</MicrosoftExtensionsProcessSourcesPackageVersion>
|
||||
<MicrosoftNETCoreApp21PackageVersion>2.1.3</MicrosoftNETCoreApp21PackageVersion>
|
||||
<MicrosoftNETCoreApp22PackageVersion>2.2.0-rtm-27023-02</MicrosoftNETCoreApp22PackageVersion>
|
||||
<MicrosoftNETTestSdkPackageVersion>15.9.0</MicrosoftNETTestSdkPackageVersion>
|
||||
<MicrosoftWebApiClientPackageVersion>5.2.6</MicrosoftWebApiClientPackageVersion>
|
||||
<NETStandardLibrary20PackageVersion>2.0.3</NETStandardLibrary20PackageVersion>
|
||||
<NewtonsoftJsonPackageVersion>11.0.2</NewtonsoftJsonPackageVersion>
|
||||
<SystemDataSqlClientPackageVersion>4.6.0-rtm-27023-03</SystemDataSqlClientPackageVersion>
|
||||
<SystemSecurityCryptographyCngPackageVersion>4.5.0</SystemSecurityCryptographyCngPackageVersion>
|
||||
<VisualStudio_NewtonsoftJsonPackageVersion>9.0.1</VisualStudio_NewtonsoftJsonPackageVersion>
|
||||
<XunitPackageVersion>2.4.0</XunitPackageVersion>
|
||||
<XunitRunnerVisualStudioPackageVersion>2.4.0</XunitRunnerVisualStudioPackageVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(DotNetPackageVersionPropsPath)" Condition=" '$(DotNetPackageVersionPropsPath)' != '' " />
|
||||
<PropertyGroup Label="Package Versions: Pinned" />
|
||||
</Project>
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="dependencies.props" />
|
||||
|
||||
<ItemGroup>
|
||||
<DotNetCoreRuntime Include="$(MicrosoftNETCoreApp22PackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- These properties are use by the automation that updates dependencies.props -->
|
||||
<LineupPackageId>Internal.AspNetCore.Universe.Lineup</LineupPackageId>
|
||||
<LineupPackageVersion>2.2.0-*</LineupPackageVersion>
|
||||
<LineupPackageRestoreSource>https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json</LineupPackageRestoreSource>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="VSIX.targets" />
|
||||
|
||||
<ItemGroup>
|
||||
<Solutions Update="$(RepositoryRoot)DotNetTools.sln">
|
||||
<!-- the 'DebugNoVSIX' and 'ReleaseNoVSIX' configurations exclude the VSIX project, which doesn't build with Microsoft.NET.Sdk yet. -->
|
||||
<AdditionalProperties>Configuration=$(Configuration)NoVSIX</AdditionalProperties>
|
||||
</Solutions>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="$(DotNetRestoreSourcePropsPath)" Condition="'$(DotNetRestoreSourcePropsPath)' != ''"/>
|
||||
|
||||
<PropertyGroup Label="RestoreSources">
|
||||
<RestoreSources>$(DotNetRestoreSources)</RestoreSources>
|
||||
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true' AND '$(AspNetUniverseBuildOffline)' != 'true' ">
|
||||
$(RestoreSources);
|
||||
https://dotnet.myget.org/F/dotnet-core/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/aspnetcore-tools/api/v3/index.json;
|
||||
https://vside.myget.org/F/vssdk/api/v3/index.json;
|
||||
</RestoreSources>
|
||||
<RestoreSources Condition="'$(DotNetBuildOffline)' != 'true'">
|
||||
$(RestoreSources);
|
||||
https://api.nuget.org/v3/index.json;
|
||||
</RestoreSources>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
|
@ -1,41 +1,41 @@
|
|||
{
|
||||
"adx": {
|
||||
"rules": [
|
||||
"AdxVerificationCompositeRule"
|
||||
],
|
||||
"packages": {
|
||||
"dotnet-watch": {
|
||||
"packageTypes": [
|
||||
"DotnetTool"
|
||||
]
|
||||
},
|
||||
"dotnet-sql-cache": {
|
||||
"packageTypes": [
|
||||
"DotnetTool"
|
||||
]
|
||||
},
|
||||
"dotnet-user-secrets": {
|
||||
"packageTypes": [
|
||||
"DotnetTool"
|
||||
]
|
||||
},
|
||||
"dotnet-dev-certs": {
|
||||
"packageTypes": [
|
||||
"DotnetTool"
|
||||
]
|
||||
},
|
||||
"Microsoft.AspNetCore.DeveloperCertificates.XPlat": {
|
||||
"Exclusions": {
|
||||
"DOC_MISSING": {
|
||||
"lib/netcoreapp2.2/Microsoft.AspNetCore.DeveloperCertificates.XPlat.dll": "Docs not required to shipoob package"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Default": {
|
||||
"rules": [
|
||||
"DefaultCompositeRule"
|
||||
]
|
||||
}
|
||||
}
|
||||
{
|
||||
"adx": {
|
||||
"rules": [
|
||||
"AdxVerificationCompositeRule"
|
||||
],
|
||||
"packages": {
|
||||
"dotnet-watch": {
|
||||
"packageTypes": [
|
||||
"DotnetTool"
|
||||
]
|
||||
},
|
||||
"dotnet-sql-cache": {
|
||||
"packageTypes": [
|
||||
"DotnetTool"
|
||||
]
|
||||
},
|
||||
"dotnet-user-secrets": {
|
||||
"packageTypes": [
|
||||
"DotnetTool"
|
||||
]
|
||||
},
|
||||
"dotnet-dev-certs": {
|
||||
"packageTypes": [
|
||||
"DotnetTool"
|
||||
]
|
||||
},
|
||||
"Microsoft.AspNetCore.DeveloperCertificates.XPlat": {
|
||||
"Exclusions": {
|
||||
"DOC_MISSING": {
|
||||
"lib/netcoreapp2.2/Microsoft.AspNetCore.DeveloperCertificates.XPlat.dll": "Docs not required to shipoob package"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Default": {
|
||||
"rules": [
|
||||
"DefaultCompositeRule"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
version:2.2.0-preview2-20181026.4
|
||||
commithash:f05a283e6c1eb66ef29a32526f75f8b567a986c9
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/release/2.2/tools/korebuild.schema.json",
|
||||
"channel": "release/2.2",
|
||||
"toolsets": {
|
||||
"visualstudio": {
|
||||
"required": [
|
||||
"windows"
|
||||
],
|
||||
"includePrerelease": true,
|
||||
"versionRange": "[15.0.26730.03, 16.0)",
|
||||
"requiredWorkloads": [
|
||||
"Microsoft.VisualStudio.Component.VSSDK"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
2
run.cmd
2
run.cmd
|
|
@ -1,2 +0,0 @@
|
|||
@ECHO OFF
|
||||
PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE"
|
||||
210
run.ps1
210
run.ps1
|
|
@ -1,210 +0,0 @@
|
|||
#!/usr/bin/env powershell
|
||||
#requires -version 4
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Executes KoreBuild commands.
|
||||
|
||||
.DESCRIPTION
|
||||
Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`.
|
||||
|
||||
.PARAMETER Command
|
||||
The KoreBuild command to run.
|
||||
|
||||
.PARAMETER Path
|
||||
The folder to build. Defaults to the folder containing this script.
|
||||
|
||||
.PARAMETER Channel
|
||||
The channel of KoreBuild to download. Overrides the value from the config file.
|
||||
|
||||
.PARAMETER DotNetHome
|
||||
The directory where .NET Core tools will be stored.
|
||||
|
||||
.PARAMETER ToolsSource
|
||||
The base url where build tools can be downloaded. Overrides the value from the config file.
|
||||
|
||||
.PARAMETER Update
|
||||
Updates KoreBuild to the latest version even if a lock file is present.
|
||||
|
||||
.PARAMETER Reinstall
|
||||
Re-installs KoreBuild
|
||||
|
||||
.PARAMETER ConfigFile
|
||||
The path to the configuration file that stores values. Defaults to korebuild.json.
|
||||
|
||||
.PARAMETER ToolsSourceSuffix
|
||||
The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores.
|
||||
|
||||
.PARAMETER CI
|
||||
Sets up CI specific settings and variables.
|
||||
|
||||
.PARAMETER Arguments
|
||||
Arguments to be passed to the command
|
||||
|
||||
.NOTES
|
||||
This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be.
|
||||
When the lockfile is not present, KoreBuild will create one using latest available version from $Channel.
|
||||
|
||||
The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set
|
||||
in the file are overridden by command line parameters.
|
||||
|
||||
.EXAMPLE
|
||||
Example config file:
|
||||
```json
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json",
|
||||
"channel": "master",
|
||||
"toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools"
|
||||
}
|
||||
```
|
||||
#>
|
||||
[CmdletBinding(PositionalBinding = $false)]
|
||||
param(
|
||||
[Parameter(Mandatory = $true, Position = 0)]
|
||||
[string]$Command,
|
||||
[string]$Path = $PSScriptRoot,
|
||||
[Alias('c')]
|
||||
[string]$Channel,
|
||||
[Alias('d')]
|
||||
[string]$DotNetHome,
|
||||
[Alias('s')]
|
||||
[string]$ToolsSource,
|
||||
[Alias('u')]
|
||||
[switch]$Update,
|
||||
[switch]$Reinstall,
|
||||
[string]$ToolsSourceSuffix,
|
||||
[string]$ConfigFile = $null,
|
||||
[switch]$CI,
|
||||
[Parameter(ValueFromRemainingArguments = $true)]
|
||||
[string[]]$Arguments
|
||||
)
|
||||
|
||||
Set-StrictMode -Version 2
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
|
||||
function Get-KoreBuild {
|
||||
|
||||
$lockFile = Join-Path $Path 'korebuild-lock.txt'
|
||||
|
||||
if (!(Test-Path $lockFile) -or $Update) {
|
||||
Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix
|
||||
}
|
||||
|
||||
$version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1
|
||||
if (!$version) {
|
||||
Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'"
|
||||
}
|
||||
$version = $version.TrimStart('version:').Trim()
|
||||
$korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version)
|
||||
|
||||
if ($Reinstall -and (Test-Path $korebuildPath)) {
|
||||
Remove-Item -Force -Recurse $korebuildPath
|
||||
}
|
||||
|
||||
if (!(Test-Path $korebuildPath)) {
|
||||
Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version"
|
||||
New-Item -ItemType Directory -Path $korebuildPath | Out-Null
|
||||
$remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip"
|
||||
|
||||
try {
|
||||
$tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip"
|
||||
Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix
|
||||
if (Get-Command -Name 'Microsoft.PowerShell.Archive\Expand-Archive' -ErrorAction Ignore) {
|
||||
# Use built-in commands where possible as they are cross-plat compatible
|
||||
Microsoft.PowerShell.Archive\Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath
|
||||
}
|
||||
else {
|
||||
# Fallback to old approach for old installations of PowerShell
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath)
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore
|
||||
throw
|
||||
}
|
||||
finally {
|
||||
Remove-Item $tmpfile -ErrorAction Ignore
|
||||
}
|
||||
}
|
||||
|
||||
return $korebuildPath
|
||||
}
|
||||
|
||||
function Join-Paths([string]$path, [string[]]$childPaths) {
|
||||
$childPaths | ForEach-Object { $path = Join-Path $path $_ }
|
||||
return $path
|
||||
}
|
||||
|
||||
function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) {
|
||||
if ($RemotePath -notlike 'http*') {
|
||||
Copy-Item $RemotePath $LocalPath
|
||||
return
|
||||
}
|
||||
|
||||
$retries = 10
|
||||
while ($retries -gt 0) {
|
||||
$retries -= 1
|
||||
try {
|
||||
Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath
|
||||
return
|
||||
}
|
||||
catch {
|
||||
Write-Verbose "Request failed. $retries retries remaining"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Error "Download failed: '$RemotePath'."
|
||||
}
|
||||
|
||||
#
|
||||
# Main
|
||||
#
|
||||
|
||||
# Load configuration or set defaults
|
||||
|
||||
$Path = Resolve-Path $Path
|
||||
if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' }
|
||||
|
||||
if (Test-Path $ConfigFile) {
|
||||
try {
|
||||
$config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json
|
||||
if ($config) {
|
||||
if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel }
|
||||
if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource}
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host -ForegroundColor Red $Error[0]
|
||||
Write-Error "$ConfigFile contains invalid JSON."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
if (!$DotNetHome) {
|
||||
$DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } `
|
||||
elseif ($CI) { Join-Path $PSScriptRoot '.dotnet' } `
|
||||
elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} `
|
||||
elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}`
|
||||
else { Join-Path $PSScriptRoot '.dotnet'}
|
||||
}
|
||||
|
||||
if (!$Channel) { $Channel = 'master' }
|
||||
if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' }
|
||||
|
||||
# Execute
|
||||
|
||||
$korebuildPath = Get-KoreBuild
|
||||
Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1')
|
||||
|
||||
try {
|
||||
Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile -CI:$CI
|
||||
Invoke-KoreBuildCommand $Command @Arguments
|
||||
}
|
||||
finally {
|
||||
Remove-Module 'KoreBuild' -ErrorAction Ignore
|
||||
}
|
||||
259
run.sh
259
run.sh
|
|
@ -1,259 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
#
|
||||
# variables
|
||||
#
|
||||
|
||||
RESET="\033[0m"
|
||||
RED="\033[0;31m"
|
||||
YELLOW="\033[0;33m"
|
||||
MAGENTA="\033[0;95m"
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
verbose=false
|
||||
update=false
|
||||
reinstall=false
|
||||
repo_path="$DIR"
|
||||
channel=''
|
||||
tools_source=''
|
||||
tools_source_suffix=''
|
||||
ci=false
|
||||
|
||||
#
|
||||
# Functions
|
||||
#
|
||||
__usage() {
|
||||
echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] <Arguments>...]"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " command The command to be run."
|
||||
echo " <Arguments>... Arguments passed to the command. Variable number of arguments allowed."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --verbose Show verbose output."
|
||||
echo " -c|--channel <CHANNEL> The channel of KoreBuild to download. Overrides the value from the config file.."
|
||||
echo " --config-file <FILE> The path to the configuration file that stores values. Defaults to korebuild.json."
|
||||
echo " -d|--dotnet-home <DIR> The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet."
|
||||
echo " --path <PATH> The directory to build. Defaults to the directory containing the script."
|
||||
echo " -s|--tools-source|-ToolsSource <URL> The base url where build tools can be downloaded. Overrides the value from the config file."
|
||||
echo " --tools-source-suffix|-ToolsSourceSuffix <SUFFIX> The suffix to append to tools-source. Useful for query strings."
|
||||
echo " -u|--update Update to the latest KoreBuild even if the lock file is present."
|
||||
echo " --reinstall Reinstall KoreBuild."
|
||||
echo " --ci Apply CI specific settings and environment variables."
|
||||
echo ""
|
||||
echo "Description:"
|
||||
echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be."
|
||||
echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel."
|
||||
|
||||
if [[ "${1:-}" != '--no-exit' ]]; then
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
get_korebuild() {
|
||||
local version
|
||||
local lock_file="$repo_path/korebuild-lock.txt"
|
||||
if [ ! -f "$lock_file" ] || [ "$update" = true ]; then
|
||||
__get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix"
|
||||
fi
|
||||
version="$(grep 'version:*' -m 1 "$lock_file")"
|
||||
if [[ "$version" == '' ]]; then
|
||||
__error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'"
|
||||
return 1
|
||||
fi
|
||||
version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
|
||||
local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version"
|
||||
|
||||
if [ "$reinstall" = true ] && [ -d "$korebuild_path" ]; then
|
||||
rm -rf "$korebuild_path"
|
||||
fi
|
||||
|
||||
{
|
||||
if [ ! -d "$korebuild_path" ]; then
|
||||
mkdir -p "$korebuild_path"
|
||||
local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip"
|
||||
tmpfile="$(mktemp)"
|
||||
echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}"
|
||||
if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then
|
||||
unzip -q -d "$korebuild_path" "$tmpfile"
|
||||
fi
|
||||
rm "$tmpfile" || true
|
||||
fi
|
||||
|
||||
source "$korebuild_path/KoreBuild.sh"
|
||||
} || {
|
||||
if [ -d "$korebuild_path" ]; then
|
||||
echo "Cleaning up after failed installation"
|
||||
rm -rf "$korebuild_path" || true
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
__error() {
|
||||
echo -e "${RED}error: $*${RESET}" 1>&2
|
||||
}
|
||||
|
||||
__warn() {
|
||||
echo -e "${YELLOW}warning: $*${RESET}"
|
||||
}
|
||||
|
||||
__machine_has() {
|
||||
hash "$1" > /dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
|
||||
__get_remote_file() {
|
||||
local remote_path=$1
|
||||
local local_path=$2
|
||||
local remote_path_suffix=$3
|
||||
|
||||
if [[ "$remote_path" != 'http'* ]]; then
|
||||
cp "$remote_path" "$local_path"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local failed=false
|
||||
if __machine_has wget; then
|
||||
wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true
|
||||
else
|
||||
failed=true
|
||||
fi
|
||||
|
||||
if [ "$failed" = true ] && __machine_has curl; then
|
||||
failed=false
|
||||
curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true
|
||||
fi
|
||||
|
||||
if [ "$failed" = true ]; then
|
||||
__error "Download failed: $remote_path" 1>&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# main
|
||||
#
|
||||
|
||||
command="${1:-}"
|
||||
shift
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-\?|-h|--help)
|
||||
__usage --no-exit
|
||||
exit 0
|
||||
;;
|
||||
-c|--channel|-Channel)
|
||||
shift
|
||||
channel="${1:-}"
|
||||
[ -z "$channel" ] && __usage
|
||||
;;
|
||||
--config-file|-ConfigFile)
|
||||
shift
|
||||
config_file="${1:-}"
|
||||
[ -z "$config_file" ] && __usage
|
||||
if [ ! -f "$config_file" ]; then
|
||||
__error "Invalid value for --config-file. $config_file does not exist."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
-d|--dotnet-home|-DotNetHome)
|
||||
shift
|
||||
DOTNET_HOME="${1:-}"
|
||||
[ -z "$DOTNET_HOME" ] && __usage
|
||||
;;
|
||||
--path|-Path)
|
||||
shift
|
||||
repo_path="${1:-}"
|
||||
[ -z "$repo_path" ] && __usage
|
||||
;;
|
||||
-s|--tools-source|-ToolsSource)
|
||||
shift
|
||||
tools_source="${1:-}"
|
||||
[ -z "$tools_source" ] && __usage
|
||||
;;
|
||||
--tools-source-suffix|-ToolsSourceSuffix)
|
||||
shift
|
||||
tools_source_suffix="${1:-}"
|
||||
[ -z "$tools_source_suffix" ] && __usage
|
||||
;;
|
||||
-u|--update|-Update)
|
||||
update=true
|
||||
;;
|
||||
--reinstall|-[Rr]einstall)
|
||||
reinstall=true
|
||||
;;
|
||||
--ci|-[Cc][Ii])
|
||||
ci=true
|
||||
if [[ -z "${DOTNET_HOME:-}" ]]; then
|
||||
DOTNET_HOME="$DIR/.dotnet"
|
||||
fi
|
||||
;;
|
||||
--verbose|-Verbose)
|
||||
verbose=true
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if ! __machine_has unzip; then
|
||||
__error 'Missing required command: unzip'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! __machine_has curl && ! __machine_has wget; then
|
||||
__error 'Missing required command. Either wget or curl is required.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json"
|
||||
if [ -f "$config_file" ]; then
|
||||
if __machine_has jq ; then
|
||||
if jq '.' "$config_file" >/dev/null ; then
|
||||
config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")"
|
||||
config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")"
|
||||
else
|
||||
__error "$config_file contains invalid JSON."
|
||||
exit 1
|
||||
fi
|
||||
elif __machine_has python ; then
|
||||
if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
|
||||
config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
|
||||
config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
|
||||
else
|
||||
__error "$config_file contains invalid JSON."
|
||||
exit 1
|
||||
fi
|
||||
elif __machine_has python3 ; then
|
||||
if python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then
|
||||
config_channel="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")"
|
||||
config_tools_source="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")"
|
||||
else
|
||||
__error "$config_file contains invalid JSON."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
__error 'Missing required command: jq or python. Could not parse the JSON file.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ ! -z "${config_channel:-}" ] && channel="$config_channel"
|
||||
[ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source"
|
||||
fi
|
||||
|
||||
[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet"
|
||||
[ -z "$channel" ] && channel='master'
|
||||
[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools'
|
||||
|
||||
get_korebuild
|
||||
set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" "$ci"
|
||||
invoke_korebuild_command "$command" "$@"
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
<!-- Intentionally empty to isolate the samples. -->
|
||||
<Project />
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
<!-- Intentionally empty to isolate the samples. -->
|
||||
<Project />
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Watch Include="say-hello.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="RunMyNpmCommand">
|
||||
<Exec Command="npm run custom" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
Launch any command with dotnet-watch
|
||||
====================================
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Install .NET Core command line. <https://dot.net/core>
|
||||
2. Install NodeJS. <https://nodejs.org>
|
||||
|
||||
## Usage
|
||||
|
||||
Open a terminal to the directory containing this project.
|
||||
|
||||
```
|
||||
dotnet watch msbuild /t:RunMyNpmCommand
|
||||
```
|
||||
|
||||
Changing the .csproj file, or the say-hello.js file will cause dotnet-watch to re-run the 'RunMyNpmCommand' target in MyApp.csproj.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"name": "any-command",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"custom": "node say-hello.js"
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
console.log("Hello from Javascript");
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
dotnet-watch samples
|
||||
====================
|
||||
|
||||
The samples in this folder show some ways to customize dotnet-watch. For full details on
|
||||
available settings and configuration, see the [README for the dotnet-watch](../../src/dotnet-watch/README.md) project.
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace WatchJavascriptFiles
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.Configure(app =>
|
||||
app.Run(async (context) =>
|
||||
{
|
||||
await context.Response.WriteAsync("Hello World!");
|
||||
}))
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
Watch JavaScript files with dotnet-watch
|
||||
========================================
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Install .NET Core command line. <https://dot.net/core>
|
||||
|
||||
## Usage
|
||||
|
||||
Open a terminal to the directory containing this project.
|
||||
|
||||
```
|
||||
dotnet watch run
|
||||
```
|
||||
|
||||
Changing the .csproj file, or \*.js file in wwwroot, or any \*.cs file will cause dotnet-watch to restart the website.
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
<Watch Include="wwwroot\**\*.js" Exclude="wwwroot\node_modules\**\*.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1 +0,0 @@
|
|||
document.title = "My awesome website";
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
Watch multiple projects with dotnet-watch
|
||||
=========================================
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Install .NET Core command line. <https://dot.net/core>
|
||||
|
||||
## Usage
|
||||
|
||||
Open a terminal to the directory containing this project.
|
||||
|
||||
```
|
||||
dotnet watch msbuild /t:TestAndRun
|
||||
```
|
||||
|
||||
The "TestAndRun" target in watch.proj will execute "dotnet test" on Test.csproj and then launch the website by calling "dotnet run" on Web.csproj.
|
||||
|
||||
Changing any \*.cs file in Test/ or Web/, any \*.csproj file, or watch.proj, will cause dotnet-watch to relaunch the "TestAndRun" target from watch.proj.
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
|
||||
<PackageReference Include="xunit" Version="2.2.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Xunit;
|
||||
|
||||
namespace Test
|
||||
{
|
||||
public class UnitTest1
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
Assert.True(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace Web
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.Configure(app =>
|
||||
app.Run(async (context) =>
|
||||
{
|
||||
await context.Response.WriteAsync("Hello World!");
|
||||
}))
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<EnableDefaultItems>false</EnableDefaultItems>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="Web\Web.csproj" />
|
||||
<ProjectReference Include="Test\Test.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="TestAndRun">
|
||||
<Exec Command="dotnet test" WorkingDirectory="Test/" />
|
||||
<Exec Command="dotnet run" WorkingDirectory="Web/" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="..\Directory.Build.props" />
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Internal.AspNetCore.Sdk" PrivateAssets="All" Version="$(InternalAspNetCoreSdkPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<Project>
|
||||
<Import Project="..\Directory.Build.targets" />
|
||||
|
||||
<Target Name="CleanPublishDir" AfterTargets="CoreClean">
|
||||
<RemoveDir Directories="$(PublishDir)" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl
|
||||
{
|
||||
public class AggregateDirectoryStructure : IDirectoryStructure
|
||||
{
|
||||
private readonly IDirectoryStructure _first;
|
||||
private readonly IDirectoryStructure _second;
|
||||
|
||||
public AggregateDirectoryStructure(IDirectoryStructure first, IDirectoryStructure second)
|
||||
{
|
||||
_first = first;
|
||||
_second = second;
|
||||
}
|
||||
|
||||
public IEnumerable<string> DirectoryNames
|
||||
{
|
||||
get
|
||||
{
|
||||
HashSet<string> values = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
values.UnionWith(_first.DirectoryNames);
|
||||
values.UnionWith(_second.DirectoryNames);
|
||||
return values.OrderBy(x => x, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
public IDirectoryStructure Parent => _first.Parent ?? _second.Parent;
|
||||
|
||||
public IDirectoryStructure GetChildDirectory(string name)
|
||||
{
|
||||
return new AggregateDirectoryStructure(_first.GetChildDirectory(name), _second.GetChildDirectory(name));
|
||||
}
|
||||
|
||||
public IRequestInfo RequestInfo => _first.RequestInfo ?? _second.RequestInfo;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,611 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.HttpRepl.Formatting;
|
||||
using Microsoft.HttpRepl.Preferences;
|
||||
using Microsoft.HttpRepl.Suggestions;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
using Microsoft.Repl.Suggestions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public abstract class BaseHttpCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>
|
||||
{
|
||||
private const string HeaderOption = nameof(HeaderOption);
|
||||
private const string ResponseHeadersFileOption = nameof(ResponseHeadersFileOption);
|
||||
private const string ResponseBodyFileOption = nameof(ResponseBodyFileOption);
|
||||
private const string ResponseFileOption = nameof(ResponseFileOption);
|
||||
private const string BodyFileOption = nameof(BodyFileOption);
|
||||
private const string NoBodyOption = nameof(NoBodyOption);
|
||||
private const string NoFormattingOption = nameof(NoFormattingOption);
|
||||
private const string StreamingOption = nameof(StreamingOption);
|
||||
private const string BodyContentOption = nameof(BodyContentOption);
|
||||
private static readonly char[] HeaderSeparatorChars = new[] { '=', ':' };
|
||||
|
||||
private CommandInputSpecification _inputSpec;
|
||||
|
||||
protected abstract string Verb { get; }
|
||||
|
||||
protected abstract bool RequiresBody { get; }
|
||||
|
||||
public override CommandInputSpecification InputSpec
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_inputSpec != null)
|
||||
{
|
||||
return _inputSpec;
|
||||
}
|
||||
|
||||
CommandInputSpecificationBuilder builder = CommandInputSpecification.Create(Verb)
|
||||
.MaximumArgCount(1)
|
||||
.WithOption(new CommandOptionSpecification(HeaderOption, requiresValue: true, forms: new[] {"--header", "-h"}))
|
||||
.WithOption(new CommandOptionSpecification(ResponseFileOption, requiresValue: true, maximumOccurrences: 1, forms: new[] { "--response", }))
|
||||
.WithOption(new CommandOptionSpecification(ResponseHeadersFileOption, requiresValue: true, maximumOccurrences: 1, forms: new[] { "--response:headers", }))
|
||||
.WithOption(new CommandOptionSpecification(ResponseBodyFileOption, requiresValue: true, maximumOccurrences: 1, forms: new[] { "--response:body", }))
|
||||
.WithOption(new CommandOptionSpecification(NoFormattingOption, maximumOccurrences: 1, forms: new[] { "--no-formatting", "-F" }))
|
||||
.WithOption(new CommandOptionSpecification(StreamingOption, maximumOccurrences: 1, forms: new[] { "--streaming", "-s" }));
|
||||
|
||||
if (RequiresBody)
|
||||
{
|
||||
builder = builder.WithOption(new CommandOptionSpecification(NoBodyOption, maximumOccurrences: 1, forms: "--no-body"))
|
||||
.WithOption(new CommandOptionSpecification(BodyFileOption, requiresValue: true, maximumOccurrences: 1, forms: new[] {"--file", "-f"}))
|
||||
.WithOption(new CommandOptionSpecification(BodyContentOption, requiresValue: true, maximumOccurrences: 1, forms: new[] {"--content", "-c"}));
|
||||
}
|
||||
|
||||
_inputSpec = builder.Finish();
|
||||
return _inputSpec;
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (programState.BaseAddress == null && (commandInput.Arguments.Count == 0 || !Uri.TryCreate(commandInput.Arguments[0].Text, UriKind.Absolute, out Uri _)))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("'set base {url}' must be called before issuing requests to a relative path".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
|
||||
if (programState.SwaggerEndpoint != null)
|
||||
{
|
||||
string swaggerRequeryBehaviorSetting = programState.GetStringPreference(WellKnownPreference.SwaggerRequeryBehavior, "auto");
|
||||
|
||||
if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, programState.SwaggerEndpoint, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, string> thisRequestHeaders = new Dictionary<string, string>();
|
||||
|
||||
foreach (InputElement header in commandInput.Options[HeaderOption])
|
||||
{
|
||||
int equalsIndex = header.Text.IndexOfAny(HeaderSeparatorChars);
|
||||
|
||||
if (equalsIndex < 0)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Headers must be formatted as {header}={value} or {header}:{value}".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
|
||||
thisRequestHeaders[header.Text.Substring(0, equalsIndex)] = header.Text.Substring(equalsIndex + 1);
|
||||
}
|
||||
|
||||
Uri effectivePath = programState.GetEffectivePath(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty);
|
||||
HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(Verb.ToUpperInvariant()), effectivePath);
|
||||
bool noBody = false;
|
||||
|
||||
if (RequiresBody)
|
||||
{
|
||||
string filePath = null;
|
||||
string bodyContent = null;
|
||||
bool deleteFile = false;
|
||||
noBody = commandInput.Options[NoBodyOption].Count > 0;
|
||||
|
||||
if (!thisRequestHeaders.TryGetValue("content-type", out string contentType) && programState.Headers.TryGetValue("content-type", out IEnumerable<string> contentTypes))
|
||||
{
|
||||
contentType = contentTypes.FirstOrDefault();
|
||||
}
|
||||
|
||||
if (!noBody)
|
||||
{
|
||||
if (string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
contentType = "application/json";
|
||||
}
|
||||
|
||||
if (commandInput.Options[BodyFileOption].Count > 0)
|
||||
{
|
||||
filePath = commandInput.Options[BodyFileOption][0].Text;
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine($"Content file {filePath} does not exist".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (commandInput.Options[BodyContentOption].Count > 0)
|
||||
{
|
||||
bodyContent = commandInput.Options[BodyContentOption][0].Text;
|
||||
}
|
||||
else
|
||||
{
|
||||
string defaultEditorCommand = programState.GetStringPreference(WellKnownPreference.DefaultEditorCommand);
|
||||
if (defaultEditorCommand == null)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine($"The default editor must be configured using the command `pref set {WellKnownPreference.DefaultEditorCommand} \"{{commandline}}\"`".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
|
||||
deleteFile = true;
|
||||
filePath = Path.GetTempFileName();
|
||||
|
||||
string exampleBody = programState.GetExampleBody(commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty, ref contentType, Verb);
|
||||
|
||||
if (!string.IsNullOrEmpty(exampleBody))
|
||||
{
|
||||
File.WriteAllText(filePath, exampleBody);
|
||||
}
|
||||
|
||||
string defaultEditorArguments = programState.GetStringPreference(WellKnownPreference.DefaultEditorArguments) ?? "";
|
||||
string original = defaultEditorArguments;
|
||||
string pathString = $"\"{filePath}\"";
|
||||
|
||||
defaultEditorArguments = defaultEditorArguments.Replace("{filename}", pathString);
|
||||
|
||||
if (string.Equals(defaultEditorArguments, original, StringComparison.Ordinal))
|
||||
{
|
||||
defaultEditorArguments = (defaultEditorArguments + " " + pathString).Trim();
|
||||
}
|
||||
|
||||
ProcessStartInfo info = new ProcessStartInfo(defaultEditorCommand, defaultEditorArguments);
|
||||
|
||||
Process.Start(info)?.WaitForExit();
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
contentType = "application/json";
|
||||
}
|
||||
|
||||
byte[] data = noBody
|
||||
? new byte[0]
|
||||
: string.IsNullOrEmpty(bodyContent)
|
||||
? File.ReadAllBytes(filePath)
|
||||
: Encoding.UTF8.GetBytes(bodyContent);
|
||||
|
||||
HttpContent content = new ByteArrayContent(data);
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
request.Content = content;
|
||||
|
||||
if (deleteFile)
|
||||
{
|
||||
File.Delete(filePath);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, IEnumerable<string>> header in programState.Headers)
|
||||
{
|
||||
content.Headers.TryAddWithoutValidation(header.Key, header.Value);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> header in thisRequestHeaders)
|
||||
{
|
||||
content.Headers.TryAddWithoutValidation(header.Key, header.Value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, IEnumerable<string>> header in programState.Headers)
|
||||
{
|
||||
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, string> header in thisRequestHeaders)
|
||||
{
|
||||
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
|
||||
}
|
||||
|
||||
string headersTarget = commandInput.Options[ResponseHeadersFileOption].FirstOrDefault()?.Text ?? commandInput.Options[ResponseFileOption].FirstOrDefault()?.Text;
|
||||
string bodyTarget = commandInput.Options[ResponseBodyFileOption].FirstOrDefault()?.Text ?? commandInput.Options[ResponseFileOption].FirstOrDefault()?.Text;
|
||||
|
||||
HttpResponseMessage response = await programState.Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
|
||||
await HandleResponseAsync(programState, commandInput, shellState.ConsoleManager, response, programState.EchoRequest, headersTarget, bodyTarget, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static async Task HandleResponseAsync(HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, IConsoleManager consoleManager, HttpResponseMessage response, bool echoRequest, string headersTargetFile, string bodyTargetFile, CancellationToken cancellationToken)
|
||||
{
|
||||
RequestConfig requestConfig = new RequestConfig(programState);
|
||||
ResponseConfig responseConfig = new ResponseConfig(programState);
|
||||
string protocolInfo;
|
||||
|
||||
if (echoRequest)
|
||||
{
|
||||
string hostString = response.RequestMessage.RequestUri.Scheme + "://" + response.RequestMessage.RequestUri.Host + (!response.RequestMessage.RequestUri.IsDefaultPort ? ":" + response.RequestMessage.RequestUri.Port : "");
|
||||
consoleManager.WriteLine($"Request to {hostString}...".SetColor(requestConfig.AddressColor));
|
||||
consoleManager.WriteLine();
|
||||
|
||||
string method = response.RequestMessage.Method.ToString().ToUpperInvariant().SetColor(requestConfig.MethodColor);
|
||||
string pathAndQuery = response.RequestMessage.RequestUri.PathAndQuery.SetColor(requestConfig.AddressColor);
|
||||
protocolInfo = $"{"HTTP".SetColor(requestConfig.ProtocolNameColor)}{"/".SetColor(requestConfig.ProtocolSeparatorColor)}{response.Version.ToString().SetColor(requestConfig.ProtocolVersionColor)}";
|
||||
|
||||
consoleManager.WriteLine($"{method} {pathAndQuery} {protocolInfo}");
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<string>>> requestHeaders = response.RequestMessage.Headers;
|
||||
|
||||
if (response.RequestMessage.Content != null)
|
||||
{
|
||||
requestHeaders = requestHeaders.Union(response.RequestMessage.Content.Headers);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, IEnumerable<string>> header in requestHeaders.OrderBy(x => x.Key))
|
||||
{
|
||||
string headerKey = header.Key.SetColor(requestConfig.HeaderKeyColor);
|
||||
string headerSep = ":".SetColor(requestConfig.HeaderSeparatorColor);
|
||||
string headerValue = string.Join(";".SetColor(requestConfig.HeaderValueSeparatorColor), header.Value.Select(x => x.Trim().SetColor(requestConfig.HeaderValueColor)));
|
||||
consoleManager.WriteLine($"{headerKey}{headerSep} {headerValue}");
|
||||
}
|
||||
|
||||
consoleManager.WriteLine();
|
||||
|
||||
if (response.RequestMessage.Content != null)
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(new MemoryStream()))
|
||||
{
|
||||
await FormatBodyAsync(commandInput, programState, consoleManager, response.RequestMessage.Content, writer, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
consoleManager.WriteLine();
|
||||
consoleManager.WriteLine($"Response from {hostString}...".SetColor(requestConfig.AddressColor));
|
||||
consoleManager.WriteLine();
|
||||
}
|
||||
|
||||
protocolInfo = $"{"HTTP".SetColor(responseConfig.ProtocolNameColor)}{"/".SetColor(responseConfig.ProtocolSeparatorColor)}{response.Version.ToString().SetColor(responseConfig.ProtocolVersionColor)}";
|
||||
string status = ((int)response.StatusCode).ToString().SetColor(responseConfig.StatusCodeColor) + " " + response.ReasonPhrase.SetColor(responseConfig.StatusReasonPhraseColor);
|
||||
|
||||
consoleManager.WriteLine($"{protocolInfo} {status}");
|
||||
|
||||
IEnumerable<KeyValuePair<string, IEnumerable<string>>> responseHeaders = response.Headers;
|
||||
|
||||
if (response.Content != null)
|
||||
{
|
||||
responseHeaders = responseHeaders.Union(response.Content.Headers);
|
||||
}
|
||||
|
||||
StreamWriter headerFileWriter;
|
||||
|
||||
if (headersTargetFile != null)
|
||||
{
|
||||
headerFileWriter = new StreamWriter(File.Create(headersTargetFile));
|
||||
}
|
||||
else
|
||||
{
|
||||
headerFileWriter = new StreamWriter(new MemoryStream());
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, IEnumerable<string>> header in responseHeaders.OrderBy(x => x.Key))
|
||||
{
|
||||
string headerKey = header.Key.SetColor(responseConfig.HeaderKeyColor);
|
||||
string headerSep = ":".SetColor(responseConfig.HeaderSeparatorColor);
|
||||
string headerValue = string.Join(";".SetColor(responseConfig.HeaderValueSeparatorColor), header.Value.Select(x => x.Trim().SetColor(responseConfig.HeaderValueColor)));
|
||||
consoleManager.WriteLine($"{headerKey}{headerSep} {headerValue}");
|
||||
headerFileWriter.WriteLine($"{header.Key}: {string.Join(";", header.Value.Select(x => x.Trim()))}");
|
||||
}
|
||||
|
||||
StreamWriter bodyFileWriter;
|
||||
if (!string.Equals(headersTargetFile, bodyTargetFile, StringComparison.Ordinal))
|
||||
{
|
||||
headerFileWriter.Flush();
|
||||
headerFileWriter.Close();
|
||||
headerFileWriter.Dispose();
|
||||
|
||||
if (bodyTargetFile != null)
|
||||
{
|
||||
bodyFileWriter = new StreamWriter(File.Create(bodyTargetFile));
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyFileWriter = new StreamWriter(new MemoryStream());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
headerFileWriter.WriteLine();
|
||||
bodyFileWriter = headerFileWriter;
|
||||
}
|
||||
|
||||
consoleManager.WriteLine();
|
||||
|
||||
if (response.Content != null)
|
||||
{
|
||||
await FormatBodyAsync(commandInput, programState, consoleManager, response.Content, bodyFileWriter, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
bodyFileWriter.Flush();
|
||||
bodyFileWriter.Close();
|
||||
bodyFileWriter.Dispose();
|
||||
|
||||
consoleManager.WriteLine();
|
||||
}
|
||||
|
||||
private static async Task FormatBodyAsync(DefaultCommandInput<ICoreParseResult> commandInput, HttpState programState, IConsoleManager consoleManager, HttpContent content, StreamWriter bodyFileWriter, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandInput.Options[StreamingOption].Count > 0)
|
||||
{
|
||||
Memory<char> buffer = new Memory<char>(new char[2048]);
|
||||
Stream s = await content.ReadAsStreamAsync().ConfigureAwait(false);
|
||||
StreamReader reader = new StreamReader(s);
|
||||
consoleManager.WriteLine("Streaming the response, press any key to stop...".SetColor(programState.WarningColor));
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
ValueTask<int> readTask = reader.ReadAsync(buffer, cancellationToken);
|
||||
if (await WaitForCompletionAsync(readTask, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
if (readTask.Result == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
string str = new string(buffer.Span.Slice(0, readTask.Result));
|
||||
consoleManager.Write(str);
|
||||
bodyFileWriter.Write(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
string contentType = null;
|
||||
if (content.Headers.TryGetValues("Content-Type", out IEnumerable<string> contentTypeValues))
|
||||
{
|
||||
contentType = contentTypeValues.FirstOrDefault()?.Split(';').FirstOrDefault();
|
||||
}
|
||||
|
||||
contentType = contentType?.ToUpperInvariant() ?? "text/plain";
|
||||
|
||||
if (commandInput.Options[NoFormattingOption].Count == 0)
|
||||
{
|
||||
if (contentType.EndsWith("/JSON", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("-JSON", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("+JSON", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("/JAVASCRIPT", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("-JAVASCRIPT", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("+JAVASCRIPT", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (await FormatJsonAsync(programState, consoleManager, content, bodyFileWriter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (contentType.EndsWith("/HTML", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("-HTML", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("+HTML", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("/XML", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("-XML", StringComparison.OrdinalIgnoreCase)
|
||||
|| contentType.EndsWith("+XML", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (await FormatXmlAsync(consoleManager, content, bodyFileWriter))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string responseContent = await content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
bodyFileWriter.WriteLine(responseContent);
|
||||
consoleManager.WriteLine(responseContent);
|
||||
}
|
||||
|
||||
private static async Task<bool> WaitForCompletionAsync(ValueTask<int> readTask, CancellationToken cancellationToken)
|
||||
{
|
||||
while (!readTask.IsCompleted && !cancellationToken.IsCancellationRequested && !Console.KeyAvailable)
|
||||
{
|
||||
await Task.Delay(1, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (Console.KeyAvailable)
|
||||
{
|
||||
Console.ReadKey(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return readTask.IsCompleted;
|
||||
}
|
||||
|
||||
private static async Task<bool> FormatXmlAsync(IWritable consoleManager, HttpContent content, StreamWriter bodyFileWriter)
|
||||
{
|
||||
string responseContent = await content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
XDocument body = XDocument.Parse(responseContent);
|
||||
consoleManager.WriteLine(body.ToString());
|
||||
bodyFileWriter.WriteLine(body.ToString());
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static async Task<bool> FormatJsonAsync(HttpState programState, IWritable outputSink, HttpContent content, StreamWriter bodyFileWriter)
|
||||
{
|
||||
string responseContent = await content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
|
||||
try
|
||||
{
|
||||
JsonConfig config = new JsonConfig(programState);
|
||||
string formatted = JsonVisitor.FormatAndColorize(config, responseContent);
|
||||
outputSink.WriteLine(formatted);
|
||||
bodyFileWriter.WriteLine(JToken.Parse(responseContent).ToString());
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)
|
||||
{
|
||||
var helpText = new StringBuilder();
|
||||
helpText.Append("Usage: ".Bold());
|
||||
helpText.AppendLine($"{Verb.ToUpperInvariant()} [Options]");
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine($"Issues a {Verb.ToUpperInvariant()} request.");
|
||||
|
||||
if (RequiresBody)
|
||||
{
|
||||
helpText.AppendLine("Your default editor will be opened with a sample body if no options are provided.");
|
||||
}
|
||||
|
||||
return helpText.ToString();
|
||||
}
|
||||
|
||||
public override string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return $"{Verb.ToLowerInvariant()} - Issues a {Verb.ToUpperInvariant()} request";
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)
|
||||
{
|
||||
List<string> results = new List<string>();
|
||||
|
||||
if (programState.Structure != null && programState.BaseAddress != null)
|
||||
{
|
||||
//If it's an absolute URI, nothing to suggest
|
||||
if (Uri.TryCreate(parseResult.Sections[1], UriKind.Absolute, out Uri _))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string path = normalCompletionString.Replace('\\', '/');
|
||||
int searchFrom = normalCompletionString.Length - 1;
|
||||
int lastSlash = path.LastIndexOf('/', searchFrom);
|
||||
string prefix;
|
||||
|
||||
if (lastSlash < 0)
|
||||
{
|
||||
path = string.Empty;
|
||||
prefix = normalCompletionString;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = path.Substring(0, lastSlash + 1);
|
||||
prefix = normalCompletionString.Substring(lastSlash + 1);
|
||||
}
|
||||
|
||||
IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);
|
||||
|
||||
foreach (string child in s.DirectoryNames)
|
||||
{
|
||||
if (child.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
results.Add(path + child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetOptionValueCompletions(IShellState shellState, HttpState programState, string optionId, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, string normalizedCompletionText)
|
||||
{
|
||||
if (string.Equals(optionId, BodyFileOption, StringComparison.Ordinal) || string.Equals(optionId, ResponseFileOption, StringComparison.OrdinalIgnoreCase) || string.Equals(optionId, ResponseBodyFileOption, StringComparison.OrdinalIgnoreCase) || string.Equals(optionId, ResponseHeadersFileOption, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return FileSystemCompletion.GetCompletions(normalizedCompletionText);
|
||||
}
|
||||
|
||||
if (string.Equals(optionId, HeaderOption, StringComparison.Ordinal))
|
||||
{
|
||||
HashSet<string> alreadySpecifiedHeaders = new HashSet<string>(StringComparer.Ordinal);
|
||||
IReadOnlyList<InputElement> options = commandInput.Options[HeaderOption];
|
||||
for (int i = 0; i < options.Count; ++i)
|
||||
{
|
||||
if (options[i] == commandInput.SelectedElement)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string elementText = options[i].Text;
|
||||
string existingHeaderName = elementText.Split(HeaderSeparatorChars)[0];
|
||||
alreadySpecifiedHeaders.Add(existingHeaderName);
|
||||
}
|
||||
|
||||
//Check to see if the selected element is in a header name or value
|
||||
int equalsIndex = normalizedCompletionText.IndexOfAny(HeaderSeparatorChars);
|
||||
string path = commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty;
|
||||
|
||||
if (equalsIndex < 0)
|
||||
{
|
||||
IEnumerable<string> headerNameOptions = HeaderCompletion.GetCompletions(alreadySpecifiedHeaders, normalizedCompletionText);
|
||||
|
||||
if (headerNameOptions == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<string> allSuggestions = new List<string>();
|
||||
foreach (string suggestion in headerNameOptions.Select(x => x))
|
||||
{
|
||||
allSuggestions.Add(suggestion + ":");
|
||||
|
||||
IEnumerable<string> suggestions = HeaderCompletion.GetValueCompletions(Verb, path, suggestion, string.Empty, programState);
|
||||
|
||||
if (suggestions != null)
|
||||
{
|
||||
foreach (string valueSuggestion in suggestions)
|
||||
{
|
||||
allSuggestions.Add(suggestion + ":" + valueSuggestion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allSuggestions;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Didn't exit from the header name check, so must be a value
|
||||
string headerName = normalizedCompletionText.Substring(0, equalsIndex);
|
||||
IEnumerable<string> suggestions = HeaderCompletion.GetValueCompletions(Verb, path, headerName, normalizedCompletionText.Substring(equalsIndex + 1), programState);
|
||||
|
||||
if (suggestions == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return suggestions.Select(x => normalizedCompletionText.Substring(0, equalsIndex + 1) + x);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.HttpRepl.Suggestions;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class ChangeDirectoryCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>
|
||||
{
|
||||
protected override Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (commandInput.Arguments.Count == 0 || string.IsNullOrEmpty(commandInput.Arguments[0]?.Text))
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine($"/{string.Join("/", programState.PathSections.Reverse())}");
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] parts = commandInput.Arguments[0].Text.Replace('\\', '/').Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (commandInput.Arguments[0].Text.StartsWith("/", StringComparison.Ordinal))
|
||||
{
|
||||
programState.PathSections.Clear();
|
||||
}
|
||||
|
||||
foreach (string part in parts)
|
||||
{
|
||||
switch (part)
|
||||
{
|
||||
case ".":
|
||||
break;
|
||||
case "..":
|
||||
if (programState.PathSections.Count > 0)
|
||||
{
|
||||
programState.PathSections.Pop();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
programState.PathSections.Push(part);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse());
|
||||
|
||||
string thisDirMethod = s.RequestInfo != null && s.RequestInfo.Methods.Count > 0
|
||||
? "[" + string.Join("|", s.RequestInfo.Methods) + "]"
|
||||
: "[]";
|
||||
|
||||
shellState.ConsoleManager.WriteLine($"/{string.Join("/", programState.PathSections.Reverse())} {thisDirMethod}");
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create("cd")
|
||||
.MaximumArgCount(1)
|
||||
.Finish();
|
||||
|
||||
protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)
|
||||
{
|
||||
var help = new StringBuilder();
|
||||
help.Append("Usage:".Bold());
|
||||
help.AppendLine("cd [directory]");
|
||||
help.AppendLine();
|
||||
help.AppendLine("Prints the current directory if no argument is specified, otherwise changes to the specified directory");
|
||||
|
||||
return help.ToString();
|
||||
}
|
||||
|
||||
public override string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return "cd [directory name] - Prints the current directory if no argument is specified, otherwise changes to the specified directory";
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)
|
||||
{
|
||||
return ServerPathCompletion.GetCompletions(programState, normalCompletionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class ClearCommand : ICommand<object, ICoreParseResult>
|
||||
{
|
||||
private static readonly string Name = "clear";
|
||||
private static readonly string AlternateName = "cls";
|
||||
|
||||
public bool? CanHandle(IShellState shellState, object programState, ICoreParseResult parseResult)
|
||||
{
|
||||
return parseResult.Sections.Count == 1 && (string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) || string.Equals(parseResult.Sections[0], AlternateName, StringComparison.OrdinalIgnoreCase))
|
||||
? (bool?) true
|
||||
: null;
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(IShellState shellState, object programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
shellState.ConsoleManager.Clear();
|
||||
shellState.CommandDispatcher.OnReady(shellState);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public string GetHelpDetails(IShellState shellState, object programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count == 1 && (string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) || string.Equals(parseResult.Sections[0], AlternateName, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return "Clears the shell";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetHelpSummary(IShellState shellState, object programState)
|
||||
{
|
||||
return "clear - Clears the shell";
|
||||
}
|
||||
|
||||
public IEnumerable<string> Suggest(IShellState shellState, object programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.SelectedSection == 0 &&
|
||||
(string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (parseResult.SelectedSection == 0 &&
|
||||
(string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || AlternateName.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.HttpRepl.Diagnostics;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class ConfigCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>
|
||||
{
|
||||
protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (programState.BaseAddress == null)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Must be connected to a server to query configuration".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(programState.DiagnosticsState.DiagnosticsEndpoint))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Diagnostics endpoint must be set to query configuration (see set diag)".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
|
||||
string configUrl = programState.DiagnosticsState.DiagnosticItems.FirstOrDefault(x => x.DisplayName == "Configuration")?.Url;
|
||||
|
||||
if (configUrl == null)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Diagnostics endpoint does not expose configuration information".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
|
||||
HttpResponseMessage response = await programState.Client.GetAsync(new Uri(programState.BaseAddress, configUrl), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Unable to get configuration information from diagnostics endpoint".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
|
||||
List<ConfigItem> configItems = await response.Content.ReadAsAsync<List<ConfigItem>>(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
foreach (ConfigItem item in configItems)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine($"{item.Key.Cyan()}: {item.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create("config").Finish();
|
||||
|
||||
protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)
|
||||
{
|
||||
return "config - Gets configuration information for the site if connected to a diagnostics endpoint";
|
||||
}
|
||||
|
||||
public override string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return "config - Gets configuration information for the site if connected to a diagnostics endpoint";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class DeleteCommand : BaseHttpCommand
|
||||
{
|
||||
protected override string Verb => "delete";
|
||||
|
||||
protected override bool RequiresBody => false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class EchoCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>
|
||||
{
|
||||
private readonly HashSet<string> _allowedModes = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {"on", "off"};
|
||||
|
||||
protected override bool CanHandle(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput)
|
||||
{
|
||||
if (commandInput.Arguments.Count == 0 || !_allowedModes.Contains(commandInput.Arguments[0]?.Text))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Allowed echo modes are 'on' and 'off'".SetColor(programState.ErrorColor));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
bool turnOn = string.Equals(commandInput.Arguments[0].Text, "on", StringComparison.OrdinalIgnoreCase);
|
||||
programState.EchoRequest = turnOn;
|
||||
|
||||
shellState.ConsoleManager.WriteLine("Request echoing is " + (turnOn ? "on" : "off"));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create("echo").ExactArgCount(1).Finish();
|
||||
|
||||
protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)
|
||||
{
|
||||
var helpText = new StringBuilder();
|
||||
helpText.Append("Usage: ".Bold());
|
||||
helpText.AppendLine($"echo [on|off]");
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine($"Turns request echoing on or off. When request echoing is on we will display a text representation of requests made by the CLI.");
|
||||
return helpText.ToString();
|
||||
}
|
||||
|
||||
public override string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return "echo [on/off] - Turns request echoing on or off";
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)
|
||||
{
|
||||
List<string> result = _allowedModes.Where(x => x.StartsWith(normalCompletionString, StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
return result.Count > 0 ? result : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class ExitCommand : CommandWithStructuredInputBase<object, ICoreParseResult>
|
||||
{
|
||||
protected override Task ExecuteAsync(IShellState shellState, object programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
shellState.IsExiting = true;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create("exit").ExactArgCount(0).Finish();
|
||||
|
||||
protected override string GetHelpDetails(IShellState shellState, object programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)
|
||||
{
|
||||
var helpText = new StringBuilder();
|
||||
helpText.Append("Usage: ".Bold());
|
||||
helpText.AppendLine($"exit");
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine($"Exits the shell");
|
||||
return helpText.ToString();
|
||||
}
|
||||
|
||||
public override string GetHelpSummary(IShellState shellState, object programState)
|
||||
{
|
||||
return "exit - Exits the shell";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class Formatter
|
||||
{
|
||||
private int _prefix;
|
||||
private int _maxDepth;
|
||||
|
||||
public void RegisterEntry(int prefixLength, int depth)
|
||||
{
|
||||
if (depth > _maxDepth)
|
||||
{
|
||||
_maxDepth = depth;
|
||||
}
|
||||
|
||||
if (prefixLength > _prefix)
|
||||
{
|
||||
_prefix = prefixLength;
|
||||
}
|
||||
}
|
||||
|
||||
public string Format(string prefix, string entry, int level)
|
||||
{
|
||||
string indent = "".PadRight(level * 4);
|
||||
return (indent + prefix).PadRight(_prefix + 3 + _maxDepth * 4) + entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class GetCommand : BaseHttpCommand
|
||||
{
|
||||
protected override string Verb => "get";
|
||||
|
||||
protected override bool RequiresBody => false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class HeadCommand : BaseHttpCommand
|
||||
{
|
||||
protected override string Verb => "head";
|
||||
|
||||
protected override bool RequiresBody => false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,256 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.HttpRepl.Preferences;
|
||||
using Microsoft.HttpRepl.Suggestions;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class HelpCommand : ICommand<HttpState, ICoreParseResult>
|
||||
{
|
||||
private static readonly string Name = "help";
|
||||
|
||||
public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
return parseResult.Sections.Count > 0 && string.Equals(parseResult.Sections[0], Name)
|
||||
? (bool?)true
|
||||
: null;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (shellState.CommandDispatcher is ICommandDispatcher<HttpState, ICoreParseResult> dispatcher)
|
||||
{
|
||||
if (parseResult.Sections.Count == 1)
|
||||
{
|
||||
CoreGetHelp(shellState, dispatcher, programState);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool anyHelp = false;
|
||||
|
||||
if (parseResult.Slice(1) is ICoreParseResult continuationParseResult)
|
||||
{
|
||||
foreach (ICommand<HttpState, ICoreParseResult> command in dispatcher.Commands)
|
||||
{
|
||||
string help = command.GetHelpDetails(shellState, programState, continuationParseResult);
|
||||
|
||||
if (!string.IsNullOrEmpty(help))
|
||||
{
|
||||
anyHelp = true;
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
shellState.ConsoleManager.WriteLine(help);
|
||||
|
||||
var structuredCommand = command as CommandWithStructuredInputBase<HttpState, ICoreParseResult>;
|
||||
if (structuredCommand != null && structuredCommand.InputSpec.Options.Any())
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
shellState.ConsoleManager.WriteLine("Options:".Bold());
|
||||
foreach (var option in structuredCommand.InputSpec.Options)
|
||||
{
|
||||
var optionText = string.Empty;
|
||||
foreach (var form in option.Forms)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(optionText))
|
||||
{
|
||||
optionText += "|";
|
||||
}
|
||||
optionText += form;
|
||||
}
|
||||
shellState.ConsoleManager.WriteLine($" {optionText}");
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyHelp)
|
||||
{
|
||||
//Maybe the input is an URL
|
||||
if (parseResult.Sections.Count == 2)
|
||||
{
|
||||
|
||||
if (programState.SwaggerEndpoint != null)
|
||||
{
|
||||
string swaggerRequeryBehaviorSetting = programState.GetStringPreference(WellKnownPreference.SwaggerRequeryBehavior, "auto");
|
||||
|
||||
if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, programState.SwaggerEndpoint, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Structure is null because, for example, SwaggerEndpoint exists but is not reachable.
|
||||
if (programState.Structure != null)
|
||||
{
|
||||
IDirectoryStructure structure = programState.Structure.TraverseTo(parseResult.Sections[1]);
|
||||
if (structure.DirectoryNames.Any())
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine("Child directories:");
|
||||
|
||||
foreach (string name in structure.DirectoryNames)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine(" " + name + "/");
|
||||
}
|
||||
anyHelp = true;
|
||||
}
|
||||
|
||||
if (structure.RequestInfo != null)
|
||||
{
|
||||
if (structure.RequestInfo.Methods.Count > 0)
|
||||
{
|
||||
if (anyHelp)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
}
|
||||
|
||||
anyHelp = true;
|
||||
shellState.ConsoleManager.WriteLine("Available methods:");
|
||||
|
||||
foreach (string method in structure.RequestInfo.Methods)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine(" " + method.ToUpperInvariant());
|
||||
IReadOnlyList<string> accepts = structure.RequestInfo.ContentTypesByMethod[method];
|
||||
string acceptsString = string.Join(", ", accepts.Where(x => !string.IsNullOrEmpty(x)));
|
||||
if (!string.IsNullOrEmpty(acceptsString))
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine(" Accepts: " + acceptsString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyHelp)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine("Unable to locate any help information for the specified command");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count > 0 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (parseResult.Sections.Count > 1)
|
||||
{
|
||||
return "Gets help about " + parseResult.Slice(1).CommandText;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Gets help";
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return "help - Gets help";
|
||||
}
|
||||
|
||||
public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.SelectedSection == 0 &&
|
||||
(string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
else if (parseResult.Sections.Count > 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (shellState.CommandDispatcher is ICommandDispatcher<HttpState, ICoreParseResult> dispatcher
|
||||
&& parseResult.Slice(1) is ICoreParseResult continuationParseResult)
|
||||
{
|
||||
HashSet<string> suggestions = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (ICommand<HttpState, ICoreParseResult> command in dispatcher.Commands)
|
||||
{
|
||||
IEnumerable<string> commandSuggestions = command.Suggest(shellState, programState, continuationParseResult);
|
||||
|
||||
if (commandSuggestions != null)
|
||||
{
|
||||
suggestions.UnionWith(commandSuggestions);
|
||||
}
|
||||
}
|
||||
|
||||
if (continuationParseResult.SelectedSection == 0)
|
||||
{
|
||||
string normalizedCompletionText = continuationParseResult.Sections[0].Substring(0, continuationParseResult.CaretPositionWithinSelectedSection);
|
||||
suggestions.UnionWith(ServerPathCompletion.GetCompletions(programState, normalizedCompletionText));
|
||||
}
|
||||
|
||||
return suggestions.OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void CoreGetHelp(IShellState shellState, ICommandDispatcher<HttpState, ICoreParseResult> dispatcher, HttpState programState)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
shellState.ConsoleManager.WriteLine("HTTP Commands:".Bold().Cyan());
|
||||
shellState.ConsoleManager.WriteLine("Use these commands to execute requests against your application.");
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
|
||||
const int navCommandColumn = -15;
|
||||
|
||||
shellState.ConsoleManager.WriteLine($"{"GET",navCommandColumn}{"Issues a GET request."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"POST",navCommandColumn}{"Issues a POST request."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"PUT",navCommandColumn}{"Issues a PUT request."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"DELETE",navCommandColumn}{"Issues a DELETE request."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"PATCH",navCommandColumn}{"Issues a PATCH request."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"HEAD",navCommandColumn}{"Issues a HEAD request."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"OPTIONS",navCommandColumn}{"Issues an OPTIONS request."}");
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
shellState.ConsoleManager.WriteLine($"{"set header",navCommandColumn}{"Sets or clears a header for all requests. e.g. `set header content-type application/json`"}");
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
shellState.ConsoleManager.WriteLine("Navigation Commands:".Bold().Cyan());
|
||||
shellState.ConsoleManager.WriteLine("The REPL allows you to navigate your URL space and focus on specific APIS that you are working on.");
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
|
||||
shellState.ConsoleManager.WriteLine($"{"set base",navCommandColumn}{"Set the base URI. e.g. `set base http://locahost:5000`"}");
|
||||
shellState.ConsoleManager.WriteLine($"{"set swagger",navCommandColumn}{"Set the URI, relative to your base if set, of the Swagger document for this API. e.g. `set swagger /swagger/v1/swagger.json`"}");
|
||||
shellState.ConsoleManager.WriteLine($"{"ls",navCommandColumn}{"Show all endpoints for the current path."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"cd",navCommandColumn}{"Append the given directory to the currently selected path, or move up a path when using `cd ..`."}");
|
||||
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
shellState.ConsoleManager.WriteLine("Shell Commands:".Bold().Cyan());
|
||||
shellState.ConsoleManager.WriteLine("Use these commands to interact with the REPL shell.");
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
|
||||
shellState.ConsoleManager.WriteLine($"{"clear",navCommandColumn}{"Removes all text from the shell."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"echo [on/off]",navCommandColumn}{"Turns request echoing on or off, show the request that was mode when using request commands."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"exit",navCommandColumn}{"Exit the shell."}");
|
||||
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
shellState.ConsoleManager.WriteLine("REPL Customization Commands:".Bold().Cyan());
|
||||
shellState.ConsoleManager.WriteLine("Use these commands to customize the REPL behavior..");
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
|
||||
shellState.ConsoleManager.WriteLine($"{"pref [get/set]",navCommandColumn}{"Allows viewing or changing preferences, e.g. 'pref set editor.command.default 'C:\\Program Files\\Microsoft VS Code\\Code.exe'`"}");
|
||||
shellState.ConsoleManager.WriteLine($"{"run",navCommandColumn}{"Runs the script at the given path. A script is a set of commands that can be typed with one command per line."}");
|
||||
shellState.ConsoleManager.WriteLine($"{"ui",navCommandColumn}{"Displays the swagger UI page, if available, in the default browser."}");
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
shellState.ConsoleManager.WriteLine("Use help <COMMAND> to learn more details about individual commands. e.g. `help get`".Bold().Cyan());
|
||||
shellState.ConsoleManager.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,187 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.HttpRepl.Preferences;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class ListCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>
|
||||
{
|
||||
private const string RecursiveOption = nameof(RecursiveOption);
|
||||
|
||||
protected override async Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (programState.SwaggerEndpoint != null)
|
||||
{
|
||||
string swaggerRequeryBehaviorSetting = programState.GetStringPreference(WellKnownPreference.SwaggerRequeryBehavior, "auto");
|
||||
|
||||
if (swaggerRequeryBehaviorSetting.StartsWith("auto", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, programState.SwaggerEndpoint, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (programState.Structure == null || programState.BaseAddress == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string path = commandInput.Arguments.Count > 0 ? commandInput.Arguments[0].Text : string.Empty;
|
||||
|
||||
//If it's an absolute URI, nothing to suggest
|
||||
if (Uri.TryCreate(path, UriKind.Absolute, out Uri _))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);
|
||||
|
||||
string thisDirMethod = s.RequestInfo != null && s.RequestInfo.Methods.Count > 0
|
||||
? "[" + string.Join("|", s.RequestInfo.Methods) + "]"
|
||||
: "[]";
|
||||
|
||||
List<TreeNode> roots = new List<TreeNode>();
|
||||
Formatter formatter = new Formatter();
|
||||
|
||||
roots.Add(new TreeNode(formatter, ".", thisDirMethod));
|
||||
|
||||
if (s.Parent != null)
|
||||
{
|
||||
string parentDirMethod = s.Parent.RequestInfo != null && s.Parent.RequestInfo.Methods.Count > 0
|
||||
? "[" + string.Join("|", s.Parent.RequestInfo.Methods) + "]"
|
||||
: "[]";
|
||||
|
||||
roots.Add(new TreeNode(formatter, "..", parentDirMethod));
|
||||
}
|
||||
|
||||
int recursionDepth = 1;
|
||||
|
||||
if (commandInput.Options[RecursiveOption].Count > 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(commandInput.Options[RecursiveOption][0]?.Text))
|
||||
{
|
||||
recursionDepth = int.MaxValue;
|
||||
}
|
||||
else if (int.TryParse(commandInput.Options[RecursiveOption][0].Text, NumberStyles.Integer, CultureInfo.InvariantCulture, out int rd) && rd > 1)
|
||||
{
|
||||
recursionDepth = rd;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string child in s.DirectoryNames)
|
||||
{
|
||||
IDirectoryStructure dir = s.GetChildDirectory(child);
|
||||
|
||||
string methods = dir.RequestInfo != null && dir.RequestInfo.Methods.Count > 0
|
||||
? "[" + string.Join("|", dir.RequestInfo.Methods) + "]"
|
||||
: "[]";
|
||||
|
||||
TreeNode dirNode = new TreeNode(formatter, child, methods);
|
||||
roots.Add(dirNode);
|
||||
Recurse(dirNode, dir, recursionDepth - 1);
|
||||
}
|
||||
|
||||
foreach (TreeNode node in roots)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine(node.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void Recurse(TreeNode parentNode, IDirectoryStructure parent, int remainingDepth)
|
||||
{
|
||||
if (remainingDepth <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string child in parent.DirectoryNames)
|
||||
{
|
||||
IDirectoryStructure dir = parent.GetChildDirectory(child);
|
||||
|
||||
string methods = dir.RequestInfo != null && dir.RequestInfo.Methods.Count > 0
|
||||
? "[" + string.Join("|", dir.RequestInfo.Methods) + "]"
|
||||
: "[]";
|
||||
|
||||
TreeNode node = parentNode.AddChild(child, methods);
|
||||
Recurse(node, dir, remainingDepth - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create("ls").AlternateName("dir")
|
||||
.MaximumArgCount(1)
|
||||
.WithOption(new CommandOptionSpecification(RecursiveOption, maximumOccurrences: 1, acceptsValue: true, forms: new[] {"-r", "--recursive"}))
|
||||
.Finish();
|
||||
|
||||
protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)
|
||||
{
|
||||
var helpText = new StringBuilder();
|
||||
helpText.Append("Usage: ".Bold());
|
||||
helpText.AppendLine($"ls [Options]");
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine($"Displays the known routes at the current location. Requires a Swagger document to be set.");
|
||||
return helpText.ToString();
|
||||
}
|
||||
|
||||
public override string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return "ls - List known routes for the current location";
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)
|
||||
{
|
||||
if (programState.Structure == null || programState.BaseAddress == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//If it's an absolute URI, nothing to suggest
|
||||
if (Uri.TryCreate(normalCompletionString, UriKind.Absolute, out Uri _))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
string path = normalCompletionString.Replace('\\', '/');
|
||||
int searchFrom = normalCompletionString.Length - 1;
|
||||
int lastSlash = path.LastIndexOf('/', searchFrom);
|
||||
string prefix;
|
||||
|
||||
if (lastSlash < 0)
|
||||
{
|
||||
path = string.Empty;
|
||||
prefix = normalCompletionString;
|
||||
}
|
||||
else
|
||||
{
|
||||
path = path.Substring(0, lastSlash + 1);
|
||||
prefix = normalCompletionString.Substring(lastSlash + 1);
|
||||
}
|
||||
|
||||
IDirectoryStructure s = programState.Structure.TraverseTo(programState.PathSections.Reverse()).TraverseTo(path);
|
||||
|
||||
List<string> results = new List<string>();
|
||||
|
||||
foreach (string child in s.DirectoryNames)
|
||||
{
|
||||
if (child.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
results.Add(path + child);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class OptionsCommand : BaseHttpCommand
|
||||
{
|
||||
protected override string Verb => "options";
|
||||
|
||||
protected override bool RequiresBody => false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class PatchCommand : BaseHttpCommand
|
||||
{
|
||||
protected override string Verb => "patch";
|
||||
|
||||
protected override bool RequiresBody => true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class PostCommand : BaseHttpCommand
|
||||
{
|
||||
protected override string Verb => "post";
|
||||
|
||||
protected override bool RequiresBody => true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,243 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.HttpRepl.Preferences;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class PrefCommand : CommandWithStructuredInputBase<HttpState, ICoreParseResult>
|
||||
{
|
||||
private readonly HashSet<string> _allowedSubcommands = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {"get", "set"};
|
||||
|
||||
public override string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return "pref [get/set] {setting} [{value}] - Allows viewing or changing preferences";
|
||||
}
|
||||
|
||||
protected override bool CanHandle(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput)
|
||||
{
|
||||
if (commandInput.Arguments.Count == 0 || !_allowedSubcommands.Contains(commandInput.Arguments[0]?.Text))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Whether get or set settings must be specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.Equals("get", commandInput.Arguments[0].Text) && (commandInput.Arguments.Count < 2 || string.IsNullOrEmpty(commandInput.Arguments[1]?.Text)))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("The preference to set must be specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override string GetHelpDetails(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult)
|
||||
{
|
||||
var helpText = new StringBuilder();
|
||||
helpText.Append("Usage: ".Bold());
|
||||
|
||||
if (commandInput.Arguments.Count == 0 || !_allowedSubcommands.Contains(commandInput.Arguments[0]?.Text))
|
||||
{
|
||||
helpText.AppendLine("pref [get/set] {setting} [{value}] - Get or sets a preference to a particular value");
|
||||
}
|
||||
else if (string.Equals(commandInput.Arguments[0].Text, "get", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
helpText.AppendLine("pref get [{setting}] - Gets the value of the specified preference or lists all preferences if no preference is specified");
|
||||
}
|
||||
else
|
||||
{
|
||||
helpText.AppendLine("pref set {setting} [{value}] - Sets (or clears if value is not specified) the value of the specified preference");
|
||||
}
|
||||
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine("Current Default Preferences:");
|
||||
foreach (var pref in programState.DefaultPreferences)
|
||||
{
|
||||
var val = pref.Value;
|
||||
if (pref.Key.Contains("colors"))
|
||||
{
|
||||
val = GetColor(val);
|
||||
}
|
||||
helpText.AppendLine($"{pref.Key,-50}{val}");
|
||||
}
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine("Current Preferences:");
|
||||
foreach (var pref in programState.Preferences)
|
||||
{
|
||||
var val = pref.Value;
|
||||
if (pref.Key.Contains("colors"))
|
||||
{
|
||||
val = GetColor(val);
|
||||
}
|
||||
helpText.AppendLine($"{pref.Key,-50}{val}");
|
||||
}
|
||||
|
||||
return helpText.ToString();
|
||||
}
|
||||
|
||||
private static string GetColor(string value)
|
||||
{
|
||||
if (value.Contains("Bold"))
|
||||
{
|
||||
value = value.Bold();
|
||||
}
|
||||
|
||||
if (value.Contains("Yellow"))
|
||||
{
|
||||
value = value.Yellow();
|
||||
}
|
||||
|
||||
if (value.Contains("Cyan"))
|
||||
{
|
||||
value = value.Cyan();
|
||||
}
|
||||
|
||||
if (value.Contains("Magenta"))
|
||||
{
|
||||
value = value.Magenta();
|
||||
}
|
||||
|
||||
if (value.Contains("Green"))
|
||||
{
|
||||
value = value.Green();
|
||||
}
|
||||
|
||||
if (value.Contains("White"))
|
||||
{
|
||||
value = value.White();
|
||||
}
|
||||
|
||||
if (value.Contains("Black"))
|
||||
{
|
||||
value = value.Black();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
protected override Task ExecuteAsync(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.Equals(commandInput.Arguments[0].Text, "get", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return GetSetting(shellState, programState, commandInput);
|
||||
}
|
||||
|
||||
return SetSetting(shellState, programState, commandInput);
|
||||
}
|
||||
|
||||
private static Task SetSetting(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput)
|
||||
{
|
||||
string prefName = commandInput.Arguments[1].Text;
|
||||
string prefValue = commandInput.Arguments.Count > 2 ? commandInput.Arguments[2]?.Text : null;
|
||||
|
||||
if (string.IsNullOrEmpty(prefValue))
|
||||
{
|
||||
if (!programState.DefaultPreferences.TryGetValue(prefName, out string defaultValue))
|
||||
{
|
||||
programState.Preferences.Remove(prefName);
|
||||
}
|
||||
else
|
||||
{
|
||||
programState.Preferences[prefName] = defaultValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
programState.Preferences[prefName] = prefValue;
|
||||
}
|
||||
|
||||
if (!programState.SavePreferences())
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Error saving preferences".SetColor(programState.ErrorColor));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static Task GetSetting(IShellState shellState, HttpState programState, DefaultCommandInput<ICoreParseResult> commandInput)
|
||||
{
|
||||
string preferenceName = commandInput.Arguments.Count > 1 ? commandInput.Arguments[1]?.Text : null;
|
||||
|
||||
//If there's a particular setting to get the value of
|
||||
if (!string.IsNullOrEmpty(preferenceName))
|
||||
{
|
||||
if (programState.Preferences.TryGetValue(preferenceName, out string value))
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine("Configured value: " + value);
|
||||
}
|
||||
else
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine((commandInput.Arguments[1].Text + " does not have a configured value").SetColor(programState.ErrorColor));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (KeyValuePair<string, string> entry in programState.Preferences.OrderBy(x => x.Key))
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine($"{entry.Key}={entry.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public override CommandInputSpecification InputSpec { get; } = CommandInputSpecification.Create("pref")
|
||||
.MinimumArgCount(1)
|
||||
.MaximumArgCount(3)
|
||||
.Finish();
|
||||
|
||||
|
||||
protected override IEnumerable<string> GetArgumentSuggestionsForText(IShellState shellState, HttpState programState, ICoreParseResult parseResult, DefaultCommandInput<ICoreParseResult> commandInput, string normalCompletionString)
|
||||
{
|
||||
if (parseResult.SelectedSection == 1)
|
||||
{
|
||||
return _allowedSubcommands.Where(x => x.StartsWith(normalCompletionString, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
if (parseResult.SelectedSection == 2)
|
||||
{
|
||||
string prefix = parseResult.Sections.Count > 2 ? normalCompletionString : string.Empty;
|
||||
List<string> matchingProperties = new List<string>();
|
||||
|
||||
foreach (string val in WellKnownPreference.Catalog.Names)
|
||||
{
|
||||
if (val.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
matchingProperties.Add(val);
|
||||
}
|
||||
}
|
||||
|
||||
return matchingProperties;
|
||||
}
|
||||
|
||||
if (parseResult.SelectedSection == 3
|
||||
&& parseResult.Sections[2].StartsWith("colors.", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
string prefix = parseResult.Sections.Count > 3 ? normalCompletionString : string.Empty;
|
||||
List<string> matchingProperties = new List<string>();
|
||||
|
||||
foreach (string val in Enum.GetNames(typeof(AllowedColors)))
|
||||
{
|
||||
if (val.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
matchingProperties.Add(val);
|
||||
}
|
||||
}
|
||||
|
||||
return matchingProperties;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class PutCommand : BaseHttpCommand
|
||||
{
|
||||
protected override string Verb => "put";
|
||||
|
||||
protected override bool RequiresBody => true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
using Microsoft.Repl.Scripting;
|
||||
using Microsoft.Repl.Suggestions;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class RunCommand : ICommand<HttpState, ICoreParseResult>
|
||||
{
|
||||
private static readonly string Name = "run";
|
||||
|
||||
public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
return parseResult.Sections.Count > 1 && parseResult.Sections.Count < 4 && string.Equals(Name, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase)
|
||||
? (bool?)true
|
||||
: null;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (!File.Exists(parseResult.Sections[1]))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine($"Could not file script file {parseResult.Sections[1]}");
|
||||
return;
|
||||
}
|
||||
|
||||
bool suppressScriptLinesInHistory = true;
|
||||
if (parseResult.Sections.Count == 3)
|
||||
{
|
||||
suppressScriptLinesInHistory = !string.Equals(parseResult.Sections[2], "+history");
|
||||
}
|
||||
|
||||
string[] lines = File.ReadAllLines(parseResult.Sections[1]);
|
||||
IScriptExecutor scriptExecutor = new ScriptExecutor<HttpState, ICoreParseResult>(suppressScriptLinesInHistory);
|
||||
await scriptExecutor.ExecuteScriptAsync(shellState, lines, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count > 0 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var helpText = new StringBuilder();
|
||||
helpText.Append("Usage: ".Bold());
|
||||
helpText.AppendLine("run {path to script}");
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine("Runs the specified script.");
|
||||
helpText.AppendLine("A script is a text file containing one CLI command per line. Each line will be run as if it was typed into the CLI.");
|
||||
return helpText.ToString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return "run {path to script} - Runs a script";
|
||||
}
|
||||
|
||||
public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.SelectedSection == 0 &&
|
||||
(string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (parseResult.SelectedSection == 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return FileSystemCompletion.GetCompletions(parseResult.Sections[1].Substring(0, parseResult.CaretPositionWithinSelectedSection));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class SetBaseCommand : ICommand<HttpState, ICoreParseResult>
|
||||
{
|
||||
private const string Name = "set";
|
||||
private const string SubCommand = "base";
|
||||
|
||||
public string Description => "Sets the base address to direct requests to.";
|
||||
|
||||
public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
return parseResult.Sections.Count > 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) && string.Equals(parseResult.Sections[1], SubCommand, StringComparison.OrdinalIgnoreCase)
|
||||
? (bool?)true
|
||||
: null;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(IShellState shellState, HttpState state, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (parseResult.Sections.Count == 2)
|
||||
{
|
||||
state.BaseAddress = null;
|
||||
}
|
||||
else if (parseResult.Sections.Count != 3 || string.IsNullOrEmpty(parseResult.Sections[2]) || !Uri.TryCreate(EnsureTrailingSlash(parseResult.Sections[2]), UriKind.Absolute, out Uri serverUri))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Must specify a server".SetColor(state.ErrorColor));
|
||||
}
|
||||
else
|
||||
{
|
||||
state.BaseAddress = serverUri;
|
||||
try
|
||||
{
|
||||
await state.Client.SendAsync(new HttpRequestMessage(HttpMethod.Head, serverUri)).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex) when (ex.InnerException is SocketException se)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine($"Warning: HEAD request to the specified address was unsuccessful ({se.Message})".SetColor(state.WarningColor));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
if (state.BaseAddress == null || !Uri.TryCreate(state.BaseAddress, "swagger.json", out Uri result))
|
||||
{
|
||||
state.SwaggerStructure = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, state, result, cancellationToken).ConfigureAwait(false);
|
||||
if (state.SwaggerStructure != null)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine("Using swagger metadata from " + result);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state.BaseAddress == null || !Uri.TryCreate(state.BaseAddress, "swagger/v1/swagger.json", out result))
|
||||
{
|
||||
state.SwaggerStructure = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
await SetSwaggerCommand.CreateDirectoryStructureForSwaggerEndpointAsync(shellState, state, result, cancellationToken).ConfigureAwait(false);
|
||||
if (state.SwaggerStructure != null)
|
||||
{
|
||||
shellState.ConsoleManager.WriteLine("Using swagger metadata from " + result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string EnsureTrailingSlash(string v)
|
||||
{
|
||||
if (!v.EndsWith("/", StringComparison.Ordinal))
|
||||
{
|
||||
v += "/";
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count > 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) && string.Equals(parseResult.Sections[1], SubCommand, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var helpText = new StringBuilder();
|
||||
helpText.Append("Usage: ".Bold());
|
||||
helpText.AppendLine($"set base [uri]");
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine(Description);
|
||||
return helpText.ToString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return Description;
|
||||
}
|
||||
|
||||
public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count == 0)
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (parseResult.Sections.Count > 0 && parseResult.SelectedSection == 0 && Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (string.Equals(Name, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 1 && (parseResult.Sections.Count < 2 || SubCommand.StartsWith(parseResult.Sections[1].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { SubCommand };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.HttpRepl.Diagnostics;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class SetDiagCommand : ICommand<HttpState, ICoreParseResult>
|
||||
{
|
||||
private static readonly string Name = "set";
|
||||
private static readonly string SubCommand = "diag";
|
||||
|
||||
public string Description => "Sets the diagnostics path to direct requests to.";
|
||||
|
||||
public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
return parseResult.Sections.Count > 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) && string.Equals(parseResult.Sections[1], SubCommand, StringComparison.OrdinalIgnoreCase)
|
||||
? (bool?)true
|
||||
: null;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (parseResult.Sections.Count == 2)
|
||||
{
|
||||
programState.DiagnosticsState.DiagnosticsEndpoint = null;
|
||||
programState.DiagnosticsState.DiagnosticItems = null;
|
||||
programState.DiagnosticsState.DiagEndpointsStructure = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (parseResult.Sections.Count != 3 || string.IsNullOrEmpty(parseResult.Sections[2]) || !Uri.TryCreate(parseResult.Sections[2], UriKind.Relative, out Uri _))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Must specify a relative path".SetColor(programState.ErrorColor));
|
||||
}
|
||||
else
|
||||
{
|
||||
programState.DiagnosticsState.DiagnosticsEndpoint = parseResult.Sections[2];
|
||||
HttpResponseMessage response = await programState.Client.GetAsync(new Uri(programState.BaseAddress, programState.DiagnosticsState.DiagnosticsEndpoint), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Unable to access diagnostics endpoint".SetColor(programState.ErrorColor));
|
||||
programState.DiagnosticsState.DiagnosticsEndpoint = null;
|
||||
programState.DiagnosticsState.DiagnosticItems = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
programState.DiagnosticsState.DiagnosticItems = (await response.Content.ReadAsAsync<Dictionary<string, DiagItem>>(cancellationToken).ConfigureAwait(false))?.Select(x => x.Value).ToList();
|
||||
|
||||
DiagItem endpointsItem = programState.DiagnosticsState.DiagnosticItems?.FirstOrDefault(x => string.Equals(x.DisplayName, "Endpoints", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (endpointsItem != null)
|
||||
{
|
||||
HttpResponseMessage endpointsResponse = await programState.Client.GetAsync(new Uri(programState.BaseAddress, endpointsItem.Url), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
if (!endpointsResponse.IsSuccessStatusCode)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Unable to get endpoints information from diagnostics endpoint".SetColor(programState.ErrorColor));
|
||||
return;
|
||||
}
|
||||
|
||||
List<DiagEndpoint> endpoints = await endpointsResponse.Content.ReadAsAsync<List<DiagEndpoint>>(cancellationToken).ConfigureAwait(false);
|
||||
DirectoryStructure structure = new DirectoryStructure(null);
|
||||
|
||||
foreach (DiagEndpoint endpoint in endpoints)
|
||||
{
|
||||
if (endpoint.Url.StartsWith(endpointsItem.Url, StringComparison.OrdinalIgnoreCase)
|
||||
|| endpoint.Url.StartsWith("/graphql", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FillDirectoryInfo(structure, endpoint.Url);
|
||||
}
|
||||
|
||||
programState.DiagnosticsState.DiagEndpointsStructure = structure;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void FillDirectoryInfo(DirectoryStructure parent, string endpoint)
|
||||
{
|
||||
string[] parts = endpoint.Split('/');
|
||||
|
||||
foreach (string part in parts)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(part))
|
||||
{
|
||||
parent = parent.DeclareDirectory(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return Description;
|
||||
}
|
||||
|
||||
public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count > 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) && string.Equals(parseResult.Sections[1], SubCommand, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return Description;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count == 0)
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (parseResult.Sections.Count > 0 && parseResult.SelectedSection == 0 && Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (string.Equals(Name, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 1 && (parseResult.Sections.Count < 2 || SubCommand.StartsWith(parseResult.Sections[1].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { SubCommand };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.HttpRepl.Suggestions;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class SetHeaderCommand : ICommand<HttpState, ICoreParseResult>
|
||||
{
|
||||
private static readonly string Name = "set";
|
||||
private static readonly string SubCommand = "header";
|
||||
|
||||
public string Description => "set header {name} [value] - Sets or clears a header";
|
||||
|
||||
public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
return parseResult.Sections.Count > 2 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) && string.Equals(parseResult.Sections[1], SubCommand, StringComparison.OrdinalIgnoreCase)
|
||||
? (bool?)true
|
||||
: null;
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (parseResult.Sections.Count == 3)
|
||||
{
|
||||
programState.Headers.Remove(parseResult.Sections[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
programState.Headers[parseResult.Sections[2]] = parseResult.Sections.Skip(3).ToList();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
var helpText = new StringBuilder();
|
||||
helpText.Append("Usage: ".Bold());
|
||||
helpText.AppendLine("set header {name} [value]");
|
||||
helpText.AppendLine();
|
||||
helpText.AppendLine("Sets or clears a header. When [value] is empty the header is cleared.");
|
||||
return Description;
|
||||
}
|
||||
|
||||
public string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return Description;
|
||||
}
|
||||
|
||||
public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count == 0)
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (parseResult.Sections.Count > 0 && parseResult.SelectedSection == 0 && Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (string.Equals(Name, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 1 && (parseResult.Sections.Count < 2 || SubCommand.StartsWith(parseResult.Sections[1].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { SubCommand };
|
||||
}
|
||||
|
||||
if (parseResult.Sections.Count > 2
|
||||
&& string.Equals(Name, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(SubCommand, parseResult.Sections[1], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 2)
|
||||
{
|
||||
string prefix = parseResult.Sections[2].Substring(0, parseResult.CaretPositionWithinSelectedSection);
|
||||
return HeaderCompletion.GetCompletions(null, prefix);
|
||||
}
|
||||
|
||||
if (parseResult.Sections.Count > 3
|
||||
&& string.Equals(Name, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase)
|
||||
&& string.Equals(SubCommand, parseResult.Sections[1], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 3)
|
||||
{
|
||||
string prefix = parseResult.Sections[3].Substring(0, parseResult.CaretPositionWithinSelectedSection);
|
||||
return HeaderCompletion.GetValueCompletions(null, string.Empty, parseResult.Sections[2], prefix, programState);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,277 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.HttpRepl.OpenApi;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class SetSwaggerCommand : ICommand<HttpState, ICoreParseResult>
|
||||
{
|
||||
private static readonly string Name = "set";
|
||||
private static readonly string SubCommand = "swagger";
|
||||
|
||||
public string Description => "Sets the swagger document to use for information about the current server";
|
||||
|
||||
private static void FillDirectoryInfo(DirectoryStructure parent, EndpointMetadata entry)
|
||||
{
|
||||
string[] parts = entry.Path.Split('/');
|
||||
|
||||
foreach (string part in parts)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(part))
|
||||
{
|
||||
parent = parent.DeclareDirectory(part);
|
||||
}
|
||||
}
|
||||
|
||||
RequestInfo dirRequestInfo = new RequestInfo();
|
||||
|
||||
foreach (KeyValuePair<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>> requestInfo in entry.AvailableRequests)
|
||||
{
|
||||
string method = requestInfo.Key;
|
||||
|
||||
foreach (KeyValuePair<string, IReadOnlyList<Parameter>> parameterSetsByContentType in requestInfo.Value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(parameterSetsByContentType.Key))
|
||||
{
|
||||
dirRequestInfo.SetFallbackRequestBody(method, parameterSetsByContentType.Key, GetBodyString(null, parameterSetsByContentType.Value));
|
||||
}
|
||||
|
||||
dirRequestInfo.SetRequestBody(method, parameterSetsByContentType.Key, GetBodyString(parameterSetsByContentType.Key, parameterSetsByContentType.Value));
|
||||
}
|
||||
|
||||
dirRequestInfo.AddMethod(method);
|
||||
}
|
||||
|
||||
if (dirRequestInfo.Methods.Count > 0)
|
||||
{
|
||||
parent.RequestInfo = dirRequestInfo;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetBodyString(string contentType, IEnumerable<Parameter> operation)
|
||||
{
|
||||
Parameter body = operation.FirstOrDefault(x => string.Equals(x.Location, "body", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (body != null)
|
||||
{
|
||||
JToken result = GenerateData(body.Schema);
|
||||
return result?.ToString() ?? "{\n}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static JToken GenerateData(Schema schema)
|
||||
{
|
||||
if (schema == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (schema.Example != null)
|
||||
{
|
||||
return JToken.FromObject(schema.Example);
|
||||
}
|
||||
|
||||
if (schema.Default != null)
|
||||
{
|
||||
return JToken.FromObject(schema.Default);
|
||||
}
|
||||
|
||||
if (schema.Type is null)
|
||||
{
|
||||
if (schema.Properties != null || schema.AdditionalProperties != null || schema.MinProperties.HasValue || schema.MaxProperties.HasValue)
|
||||
{
|
||||
schema.Type = "OBJECT";
|
||||
}
|
||||
else if (schema.Items != null || schema.MinItems.HasValue || schema.MaxItems.HasValue)
|
||||
{
|
||||
schema.Type = "ARRAY";
|
||||
}
|
||||
else if (schema.Minimum.HasValue || schema.Maximum.HasValue || schema.MultipleOf.HasValue)
|
||||
{
|
||||
schema.Type = "INTEGER";
|
||||
}
|
||||
}
|
||||
|
||||
switch (schema.Type?.ToUpperInvariant())
|
||||
{
|
||||
case null:
|
||||
case "STRING":
|
||||
return "";
|
||||
case "NUMBER":
|
||||
if (schema.Minimum.HasValue)
|
||||
{
|
||||
if (schema.Maximum.HasValue)
|
||||
{
|
||||
return (schema.Maximum.Value + schema.Minimum.Value) / 2;
|
||||
}
|
||||
|
||||
if (schema.ExclusiveMinimum)
|
||||
{
|
||||
return schema.Minimum.Value + 1;
|
||||
}
|
||||
|
||||
return schema.Minimum.Value;
|
||||
}
|
||||
return 1.1;
|
||||
case "INTEGER":
|
||||
if (schema.Minimum.HasValue)
|
||||
{
|
||||
if (schema.Maximum.HasValue)
|
||||
{
|
||||
return (int)((schema.Maximum.Value + schema.Minimum.Value) / 2);
|
||||
}
|
||||
|
||||
if (schema.ExclusiveMinimum)
|
||||
{
|
||||
return schema.Minimum.Value + 1;
|
||||
}
|
||||
|
||||
return schema.Minimum.Value;
|
||||
}
|
||||
return 0;
|
||||
case "BOOLEAN":
|
||||
return true;
|
||||
case "ARRAY":
|
||||
JArray container = new JArray();
|
||||
JToken item = GenerateData(schema.Items) ?? "";
|
||||
|
||||
int count = schema.MinItems.GetValueOrDefault();
|
||||
count = Math.Max(1, count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
container.Add(item.DeepClone());
|
||||
}
|
||||
|
||||
return container;
|
||||
case "OBJECT":
|
||||
JObject obj = new JObject();
|
||||
foreach (KeyValuePair<string, Schema> property in schema.Properties)
|
||||
{
|
||||
JToken data = GenerateData(property.Value) ?? "";
|
||||
obj[property.Key] = data;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static async Task<IEnumerable<EndpointMetadata>> GetSwaggerDocAsync(HttpClient client, Uri uri)
|
||||
{
|
||||
var resp = await client.GetAsync(uri).ConfigureAwait(false);
|
||||
resp.EnsureSuccessStatusCode();
|
||||
string responseString = await resp.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
JsonSerializer serializer = new JsonSerializer{ PreserveReferencesHandling = PreserveReferencesHandling.All };
|
||||
JObject responseObject = (JObject)serializer.Deserialize(new StringReader(responseString), typeof(JObject));
|
||||
EndpointMetadataReader reader = new EndpointMetadataReader();
|
||||
responseObject = await PointerUtil.ResolvePointersAsync(uri, responseObject, client).ConfigureAwait(false) as JObject;
|
||||
|
||||
if (responseObject is null)
|
||||
{
|
||||
return new EndpointMetadata[0];
|
||||
}
|
||||
|
||||
return reader.Read(responseObject);
|
||||
}
|
||||
|
||||
public string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return Description;
|
||||
}
|
||||
|
||||
public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count > 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) && string.Equals(parseResult.Sections[1], SubCommand, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return Description;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count == 0)
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (parseResult.Sections.Count > 0 && parseResult.SelectedSection == 0 && Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
if (string.Equals(Name, parseResult.Sections[0], StringComparison.OrdinalIgnoreCase) && parseResult.SelectedSection == 1 && (parseResult.Sections.Count < 2 || SubCommand.StartsWith(parseResult.Sections[1].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { SubCommand };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
return parseResult.Sections.Count > 1 && string.Equals(parseResult.Sections[0], Name, StringComparison.OrdinalIgnoreCase) && string.Equals(parseResult.Sections[1], SubCommand, StringComparison.OrdinalIgnoreCase)
|
||||
? (bool?)true
|
||||
: null;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (parseResult.Sections.Count == 2)
|
||||
{
|
||||
programState.SwaggerStructure = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (parseResult.Sections.Count != 3 || string.IsNullOrEmpty(parseResult.Sections[2]) || !Uri.TryCreate(parseResult.Sections[2], UriKind.Absolute, out Uri serverUri))
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Must specify a swagger document".SetColor(programState.ErrorColor));
|
||||
}
|
||||
else
|
||||
{
|
||||
await CreateDirectoryStructureForSwaggerEndpointAsync(shellState, programState, serverUri, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task CreateDirectoryStructureForSwaggerEndpointAsync(IShellState shellState, HttpState programState, Uri serverUri, CancellationToken cancellationToken)
|
||||
{
|
||||
programState.SwaggerEndpoint = serverUri;
|
||||
|
||||
try
|
||||
{
|
||||
IEnumerable<EndpointMetadata> doc = await GetSwaggerDocAsync(programState.Client, serverUri).ConfigureAwait(false);
|
||||
|
||||
DirectoryStructure d = new DirectoryStructure(null);
|
||||
|
||||
foreach (EndpointMetadata entry in doc)
|
||||
{
|
||||
FillDirectoryInfo(d, entry);
|
||||
}
|
||||
|
||||
programState.SwaggerStructure = !cancellationToken.IsCancellationRequested ? d : null;
|
||||
}
|
||||
catch
|
||||
{
|
||||
programState.SwaggerStructure = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class TreeNode
|
||||
{
|
||||
private readonly int _depth;
|
||||
private readonly Formatter _formatter;
|
||||
private readonly string _prefix;
|
||||
private readonly string _entry;
|
||||
private readonly List<TreeNode> _children = new List<TreeNode>();
|
||||
|
||||
public TreeNode(Formatter formatter, string prefix, string entry)
|
||||
: this(formatter, prefix, entry, 0)
|
||||
{
|
||||
}
|
||||
|
||||
private TreeNode(Formatter formatter, string prefix, string entry, int depth)
|
||||
{
|
||||
_formatter = formatter;
|
||||
formatter.RegisterEntry(prefix.Length, depth);
|
||||
_prefix = prefix;
|
||||
_entry = entry;
|
||||
_depth = depth;
|
||||
}
|
||||
|
||||
public TreeNode AddChild(string prefix, string entry)
|
||||
{
|
||||
TreeNode child = new TreeNode(_formatter, prefix, entry, _depth + 1);
|
||||
_children.Add(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string self = _formatter.Format(_prefix, _entry, _depth);
|
||||
|
||||
if (_children.Count == 0)
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
return self + Environment.NewLine + string.Join(Environment.NewLine, _children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Repl;
|
||||
using Microsoft.Repl.Commanding;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Microsoft.Repl.Parsing;
|
||||
|
||||
namespace Microsoft.HttpRepl.Commands
|
||||
{
|
||||
public class UICommand : ICommand<HttpState, ICoreParseResult>
|
||||
{
|
||||
private static readonly string Name = "ui";
|
||||
|
||||
public bool? CanHandle(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
return parseResult.Sections.Count == 1 && string.Equals(parseResult.Sections[0], Name)
|
||||
? (bool?)true
|
||||
: null;
|
||||
}
|
||||
|
||||
public Task ExecuteAsync(IShellState shellState, HttpState programState, ICoreParseResult parseResult, CancellationToken cancellationToken)
|
||||
{
|
||||
if (programState.BaseAddress == null)
|
||||
{
|
||||
shellState.ConsoleManager.Error.WriteLine("Must be connected to a server to launch Swagger UI".SetColor(programState.ErrorColor));
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Uri uri = new Uri(programState.BaseAddress, "swagger");
|
||||
string agent = "cmd";
|
||||
string agentParam = $"/c start {uri.AbsoluteUri}";
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
agent = "open";
|
||||
agentParam = uri.AbsoluteUri;
|
||||
}
|
||||
else if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
agent = "xdg-open";
|
||||
agentParam = uri.AbsoluteUri;
|
||||
}
|
||||
|
||||
Process.Start(new ProcessStartInfo(agent, agentParam) { CreateNoWindow = true });
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public string GetHelpDetails(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.Sections.Count == 1 && string.Equals(parseResult.Sections[0], Name))
|
||||
{
|
||||
return "ui - Launches the Swagger UI page (if available) in the default browser";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetHelpSummary(IShellState shellState, HttpState programState)
|
||||
{
|
||||
return "ui - Launches the Swagger UI page (if available) in the default browser";
|
||||
}
|
||||
|
||||
public IEnumerable<string> Suggest(IShellState shellState, HttpState programState, ICoreParseResult parseResult)
|
||||
{
|
||||
if (parseResult.SelectedSection == 0 &&
|
||||
(string.IsNullOrEmpty(parseResult.Sections[parseResult.SelectedSection]) || Name.StartsWith(parseResult.Sections[0].Substring(0, parseResult.CaretPositionWithinSelectedSection), StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new[] { Name };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Diagnostics
|
||||
{
|
||||
public class ConfigItem
|
||||
{
|
||||
public string Key { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Diagnostics
|
||||
{
|
||||
public class DiagEndpoint
|
||||
{
|
||||
public string DisplayName { get; set; }
|
||||
public string Url { get; set; }
|
||||
public DiagEndpointMetadata[] Metadata { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Diagnostics
|
||||
{
|
||||
public class DiagEndpointMetadata
|
||||
{
|
||||
public object Item { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string[] Interfaces { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.Diagnostics
|
||||
{
|
||||
public class DiagItem
|
||||
{
|
||||
public string DisplayName { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.HttpRepl.Diagnostics
|
||||
{
|
||||
public class DiagnosticsState
|
||||
{
|
||||
public string DiagnosticsEndpoint { get; set; }
|
||||
|
||||
public IReadOnlyList<DiagItem> DiagnosticItems { get; internal set; }
|
||||
|
||||
public IDirectoryStructure DiagEndpointsStructure { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl
|
||||
{
|
||||
public class DirectoryStructure : IDirectoryStructure
|
||||
{
|
||||
private readonly Dictionary<string, DirectoryStructure> _childDirectories = new Dictionary<string, DirectoryStructure>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public DirectoryStructure(IDirectoryStructure parent)
|
||||
{
|
||||
Parent = parent;
|
||||
}
|
||||
|
||||
public IEnumerable<string> DirectoryNames => _childDirectories.Keys;
|
||||
|
||||
public IDirectoryStructure Parent { get; }
|
||||
|
||||
public DirectoryStructure DeclareDirectory(string name)
|
||||
{
|
||||
if (_childDirectories.TryGetValue(name, out DirectoryStructure existing))
|
||||
{
|
||||
return existing;
|
||||
}
|
||||
|
||||
return _childDirectories[name] = new DirectoryStructure(this);
|
||||
}
|
||||
|
||||
public IDirectoryStructure GetChildDirectory(string name)
|
||||
{
|
||||
if (_childDirectories.TryGetValue(name, out DirectoryStructure result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
IDirectoryStructure parameterizedTarget = _childDirectories.FirstOrDefault(x => x.Key.StartsWith('{') && x.Key.EndsWith('}')).Value;
|
||||
|
||||
if (!(parameterizedTarget is null))
|
||||
{
|
||||
return parameterizedTarget;
|
||||
}
|
||||
|
||||
return new DirectoryStructure(this);
|
||||
}
|
||||
|
||||
public IRequestInfo RequestInfo { get; set; }
|
||||
}
|
||||
|
||||
public class RequestInfo : IRequestInfo
|
||||
{
|
||||
private readonly HashSet<string> _methods = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, Dictionary<string, string>> _requestBodiesByMethodByContentType = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, string> _fallbackBodyStringsByMethod = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, string> _fallbackContentTypeStringsByMethod = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly Dictionary<string, IReadOnlyList<string>> _contentTypesByMethod = new Dictionary<string, IReadOnlyList<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public IReadOnlyList<string> Methods => _methods.ToList();
|
||||
|
||||
public IReadOnlyDictionary<string, IReadOnlyList<string>> ContentTypesByMethod => _contentTypesByMethod;
|
||||
|
||||
public string GetRequestBodyForContentType(ref string contentType, string method)
|
||||
{
|
||||
if (_requestBodiesByMethodByContentType.TryGetValue(method, out Dictionary<string, string> bodiesByContentType)
|
||||
&& bodiesByContentType.TryGetValue(contentType, out string body))
|
||||
{
|
||||
return body;
|
||||
}
|
||||
|
||||
if (_fallbackBodyStringsByMethod.TryGetValue(method, out body))
|
||||
{
|
||||
if (_fallbackContentTypeStringsByMethod.TryGetValue(method, out string newContentType))
|
||||
{
|
||||
contentType = newContentType;
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetRequestBody(string method, string contentType, string body)
|
||||
{
|
||||
if (!_requestBodiesByMethodByContentType.TryGetValue(method, out Dictionary<string, string> bodiesByContentType))
|
||||
{
|
||||
_requestBodiesByMethodByContentType[method] = bodiesByContentType = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
if (!_contentTypesByMethod.TryGetValue(method, out IReadOnlyList<string> contentTypesRaw))
|
||||
{
|
||||
_contentTypesByMethod[method] = contentTypesRaw = new List<string>();
|
||||
}
|
||||
|
||||
List<string> contentTypes = (List<string>)contentTypesRaw;
|
||||
contentTypes.Add(contentType);
|
||||
|
||||
bodiesByContentType[contentType] = body;
|
||||
}
|
||||
|
||||
public void AddMethod(string method)
|
||||
{
|
||||
_methods.Add(method);
|
||||
}
|
||||
|
||||
public void SetFallbackRequestBody(string method, string contentType, string fallbackBodyString)
|
||||
{
|
||||
_fallbackBodyStringsByMethod[method] = fallbackBodyString;
|
||||
_fallbackContentTypeStringsByMethod[method] = contentType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl
|
||||
{
|
||||
public static class DirectoryStructureExtensions
|
||||
{
|
||||
public static IEnumerable<string> GetDirectoryListingAtPath(this IDirectoryStructure structure, string path)
|
||||
{
|
||||
return structure.TraverseTo(path).DirectoryNames;
|
||||
}
|
||||
|
||||
public static IDirectoryStructure TraverseTo(this IDirectoryStructure structure, string path)
|
||||
{
|
||||
string[] parts = path.Replace('\\', '/').Split('/');
|
||||
return structure.TraverseTo(parts);
|
||||
}
|
||||
|
||||
public static IDirectoryStructure TraverseTo(this IDirectoryStructure structure, IEnumerable<string> pathParts)
|
||||
{
|
||||
IDirectoryStructure s = structure;
|
||||
IReadOnlyList<string> parts = pathParts.ToList();
|
||||
|
||||
if (parts.Count == 0)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
||||
if (parts[0] == string.Empty && parts.Count > 1)
|
||||
{
|
||||
while (s.Parent != null)
|
||||
{
|
||||
s = s.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string part in parts)
|
||||
{
|
||||
if (part == ".")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part == "..")
|
||||
{
|
||||
s = s.Parent ?? s;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(part))
|
||||
{
|
||||
s = s.GetChildDirectory(part);
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.HttpRepl.Preferences;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.HttpRepl.Formatting
|
||||
{
|
||||
public static class JsonVisitor
|
||||
{
|
||||
public static string FormatAndColorize(IJsonConfig config, string jsonData)
|
||||
{
|
||||
if (jsonData == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
JsonTextReader reader = new JsonTextReader(new StringReader(jsonData));
|
||||
bool isValuePosition = false;
|
||||
bool isTerminalValue = false;
|
||||
bool isFirstToken = true;
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (!isValuePosition)
|
||||
{
|
||||
//If we're about to write an end object/array, we shouldn't have a comma
|
||||
if (reader.TokenType != JsonToken.EndArray && reader.TokenType != JsonToken.EndObject
|
||||
&& isTerminalValue)
|
||||
{
|
||||
result.Append(",".SetColor(config.CommaColor));
|
||||
}
|
||||
|
||||
if (!isFirstToken)
|
||||
{
|
||||
result.AppendLine();
|
||||
}
|
||||
}
|
||||
|
||||
isFirstToken = false;
|
||||
|
||||
if (!isValuePosition)
|
||||
{
|
||||
result.Append("".PadLeft(reader.Depth * config.IndentSize));
|
||||
}
|
||||
|
||||
isTerminalValue = false;
|
||||
isValuePosition = false;
|
||||
JsonToken type = reader.TokenType;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JsonToken.StartObject:
|
||||
result.Append("{".SetColor(config.ObjectBraceColor));
|
||||
break;
|
||||
case JsonToken.EndObject:
|
||||
result.Append("}".SetColor(config.ObjectBraceColor));
|
||||
isTerminalValue = true;
|
||||
break;
|
||||
case JsonToken.StartArray:
|
||||
result.Append("[".SetColor(config.ArrayBraceColor));
|
||||
break;
|
||||
case JsonToken.EndArray:
|
||||
result.Append("]".SetColor(config.ArrayBraceColor));
|
||||
isTerminalValue = true;
|
||||
break;
|
||||
case JsonToken.PropertyName:
|
||||
result.Append((reader.QuoteChar.ToString() + reader.Value + reader.QuoteChar).SetColor(config.NameColor) + ": ".SetColor(config.NameSeparatorColor));
|
||||
isValuePosition = true;
|
||||
break;
|
||||
case JsonToken.Boolean:
|
||||
result.Append(reader.Value.ToString().ToLowerInvariant().SetColor(config.BoolColor));
|
||||
isTerminalValue = true;
|
||||
break;
|
||||
case JsonToken.Integer:
|
||||
case JsonToken.Float:
|
||||
result.Append(reader.Value.ToString().ToLowerInvariant().SetColor(config.NumericColor));
|
||||
isTerminalValue = true;
|
||||
break;
|
||||
case JsonToken.Null:
|
||||
result.Append("null".SetColor(config.NullColor));
|
||||
isTerminalValue = true;
|
||||
break;
|
||||
case JsonToken.Comment:
|
||||
result.Append(("//" + reader.Value).SetColor(config.NumericColor));
|
||||
break;
|
||||
case JsonToken.String:
|
||||
result.Append((reader.QuoteChar.ToString() + reader.Value + reader.QuoteChar.ToString()).SetColor(config.StringColor));
|
||||
isTerminalValue = true;
|
||||
break;
|
||||
case JsonToken.Raw:
|
||||
case JsonToken.Date:
|
||||
case JsonToken.Bytes:
|
||||
case JsonToken.Undefined:
|
||||
case JsonToken.None:
|
||||
result.Append(reader.Value.ToString().SetColor(config.DefaultColor));
|
||||
isTerminalValue = true;
|
||||
break;
|
||||
case JsonToken.EndConstructor:
|
||||
case JsonToken.StartConstructor:
|
||||
default:
|
||||
result.Append(reader.Value.ToString().SetColor(config.DefaultColor));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,380 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.HttpRepl.Diagnostics;
|
||||
using Microsoft.HttpRepl.Preferences;
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
|
||||
namespace Microsoft.HttpRepl
|
||||
{
|
||||
public class HttpState
|
||||
{
|
||||
private string _userProfileDir;
|
||||
private string _prefsFilePath;
|
||||
|
||||
public HttpClient Client { get; }
|
||||
|
||||
public AllowedColors ErrorColor => this.GetColorPreference(WellKnownPreference.ErrorColor, AllowedColors.BoldRed);
|
||||
|
||||
public AllowedColors WarningColor => this.GetColorPreference(WellKnownPreference.WarningColor, AllowedColors.BoldYellow);
|
||||
|
||||
public Stack<string> PathSections { get; }
|
||||
|
||||
public IDirectoryStructure SwaggerStructure { get; set; }
|
||||
|
||||
public IDirectoryStructure Structure => DiagnosticsState.DiagEndpointsStructure == null
|
||||
? SwaggerStructure
|
||||
: SwaggerStructure == null
|
||||
? DiagnosticsState.DiagEndpointsStructure
|
||||
: new AggregateDirectoryStructure(SwaggerStructure, DiagnosticsState.DiagEndpointsStructure);
|
||||
|
||||
public Uri BaseAddress { get; set; }
|
||||
|
||||
public bool EchoRequest { get; set; }
|
||||
|
||||
public Dictionary<string, string> Preferences { get; }
|
||||
|
||||
public IReadOnlyDictionary<string, string> DefaultPreferences { get; }
|
||||
|
||||
public string UserProfileDir
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_userProfileDir == null)
|
||||
{
|
||||
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
||||
string profileDir = Environment.GetEnvironmentVariable(isWindows
|
||||
? "USERPROFILE"
|
||||
: "HOME");
|
||||
|
||||
_userProfileDir = profileDir;
|
||||
}
|
||||
|
||||
return _userProfileDir;
|
||||
}
|
||||
}
|
||||
|
||||
public string PrefsFilePath => _prefsFilePath ?? (_prefsFilePath = Path.Combine(UserProfileDir, ".httpreplprefs"));
|
||||
|
||||
public Dictionary<string, IEnumerable<string>> Headers { get; }
|
||||
|
||||
public DiagnosticsState DiagnosticsState { get; }
|
||||
|
||||
public Uri SwaggerEndpoint { get; set; }
|
||||
|
||||
public HttpState()
|
||||
{
|
||||
Client = new HttpClient();
|
||||
PathSections = new Stack<string>();
|
||||
Preferences = new Dictionary<string, string>();
|
||||
DefaultPreferences = CreateDefaultPreferencs();
|
||||
Headers = new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "User-Agent", new[] { "HTTP-REPL" } }
|
||||
};
|
||||
Preferences = new Dictionary<string, string>(DefaultPreferences);
|
||||
LoadPreferences();
|
||||
DiagnosticsState = new DiagnosticsState();
|
||||
}
|
||||
|
||||
public string GetPrompt()
|
||||
{
|
||||
return $"{GetEffectivePath(new string[0], false, out int _)?.ToString() ?? "(Disconnected)"}~ ";
|
||||
}
|
||||
|
||||
private void LoadPreferences()
|
||||
{
|
||||
if (File.Exists(PrefsFilePath))
|
||||
{
|
||||
string[] prefsFile = File.ReadAllLines(PrefsFilePath);
|
||||
|
||||
foreach (string line in prefsFile)
|
||||
{
|
||||
int equalsIndex = line.IndexOf('=');
|
||||
|
||||
if (equalsIndex < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Preferences[line.Substring(0, equalsIndex)] = line.Substring(equalsIndex + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IReadOnlyDictionary<string, string> CreateDefaultPreferencs()
|
||||
{
|
||||
return new Dictionary<string, string>
|
||||
{
|
||||
{ WellKnownPreference.ProtocolColor, "BoldGreen" },
|
||||
{ WellKnownPreference.StatusColor, "BoldYellow" },
|
||||
|
||||
{ WellKnownPreference.JsonArrayBraceColor, "BoldCyan" },
|
||||
{ WellKnownPreference.JsonCommaColor, "BoldYellow" },
|
||||
{ WellKnownPreference.JsonNameColor, "BoldMagenta" },
|
||||
{ WellKnownPreference.JsonNameSeparatorColor, "BoldWhite" },
|
||||
{ WellKnownPreference.JsonObjectBraceColor, "Cyan" },
|
||||
{ WellKnownPreference.JsonColor, "Green" }
|
||||
};
|
||||
}
|
||||
|
||||
public bool SavePreferences()
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
foreach (KeyValuePair<string, string> entry in Preferences.OrderBy(x => x.Key))
|
||||
{
|
||||
//If the value didn't exist in the defaults or the value's different, include it in the user's preferences file
|
||||
if (!DefaultPreferences.TryGetValue(entry.Key, out string value) || !string.Equals(value, entry.Value, StringComparison.Ordinal))
|
||||
{
|
||||
lines.Add($"{entry.Key}={entry.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File.WriteAllLines(PrefsFilePath, lines);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetExampleBody(string path, ref string contentType, string method)
|
||||
{
|
||||
Uri effectivePath = GetEffectivePath(path);
|
||||
string rootRelativePath = effectivePath.LocalPath.Substring(BaseAddress.LocalPath.Length).TrimStart('/');
|
||||
IDirectoryStructure structure = SwaggerStructure?.TraverseTo(rootRelativePath);
|
||||
return structure?.RequestInfo?.GetRequestBodyForContentType(ref contentType, method);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetApplicableContentTypes(string method, string path)
|
||||
{
|
||||
Uri effectivePath = GetEffectivePath(path);
|
||||
string rootRelativePath = effectivePath.LocalPath.Substring(BaseAddress.LocalPath.Length).TrimStart('/');
|
||||
IDirectoryStructure structure = SwaggerStructure?.TraverseTo(rootRelativePath);
|
||||
IReadOnlyDictionary<string, IReadOnlyList<string>> contentTypesByMethod = structure?.RequestInfo?.ContentTypesByMethod;
|
||||
|
||||
if (contentTypesByMethod != null)
|
||||
{
|
||||
if (method is null)
|
||||
{
|
||||
return contentTypesByMethod.Values.SelectMany(x => x).Distinct(StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
if (contentTypesByMethod.TryGetValue(method, out IReadOnlyList<string> contentTypes))
|
||||
{
|
||||
return contentTypes;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Uri GetEffectivePath(string commandSpecifiedPath)
|
||||
{
|
||||
if (Uri.TryCreate(commandSpecifiedPath, UriKind.Absolute, out Uri absoluteUri))
|
||||
{
|
||||
return absoluteUri;
|
||||
}
|
||||
|
||||
UriBuilder builder = new UriBuilder(BaseAddress);
|
||||
string path = string.Join('/', PathSections.Reverse());
|
||||
string[] parts = path.Split('?');
|
||||
string query = null;
|
||||
string query2 = null;
|
||||
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
path = parts[0];
|
||||
query = string.Join('?', parts.Skip(1));
|
||||
}
|
||||
|
||||
builder.Path += path;
|
||||
|
||||
if (commandSpecifiedPath.Length > 0)
|
||||
{
|
||||
if (commandSpecifiedPath[0] != '/')
|
||||
{
|
||||
string argPath = commandSpecifiedPath;
|
||||
if (builder.Path.Length > 0 && builder.Path[builder.Path.Length - 1] != '/')
|
||||
{
|
||||
argPath = "/" + argPath;
|
||||
}
|
||||
|
||||
int queryIndex = argPath.IndexOf('?');
|
||||
path = argPath;
|
||||
|
||||
if (queryIndex > -1)
|
||||
{
|
||||
query2 = argPath.Substring(queryIndex + 1);
|
||||
path = argPath.Substring(0, queryIndex);
|
||||
}
|
||||
|
||||
builder.Path += path;
|
||||
}
|
||||
else
|
||||
{
|
||||
int queryIndex = commandSpecifiedPath.IndexOf('?');
|
||||
path = commandSpecifiedPath;
|
||||
|
||||
if (queryIndex > -1)
|
||||
{
|
||||
query2 = commandSpecifiedPath.Substring(queryIndex + 1);
|
||||
path = commandSpecifiedPath.Substring(0, queryIndex);
|
||||
}
|
||||
|
||||
builder.Path = path;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
int queryIndex = commandSpecifiedPath.IndexOf('?');
|
||||
path = commandSpecifiedPath;
|
||||
|
||||
if (queryIndex > -1)
|
||||
{
|
||||
query2 = commandSpecifiedPath.Substring(queryIndex + 1);
|
||||
path = commandSpecifiedPath.Substring(0, queryIndex);
|
||||
}
|
||||
|
||||
builder.Path += path;
|
||||
}
|
||||
|
||||
if (query != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(builder.Query))
|
||||
{
|
||||
query = "&" + query;
|
||||
}
|
||||
|
||||
builder.Query += query;
|
||||
}
|
||||
|
||||
if (query2 != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(builder.Query))
|
||||
{
|
||||
query2 = "&" + query2;
|
||||
}
|
||||
|
||||
builder.Query += query2;
|
||||
}
|
||||
|
||||
return builder.Uri;
|
||||
}
|
||||
|
||||
public Uri GetEffectivePath(IReadOnlyList<string> sections, bool requiresBody, out int filePathIndex)
|
||||
{
|
||||
filePathIndex = 1;
|
||||
|
||||
if (BaseAddress == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
UriBuilder builder = new UriBuilder(BaseAddress);
|
||||
string path = string.Join('/', PathSections.Reverse());
|
||||
string[] parts = path.Split('?');
|
||||
string query = null;
|
||||
string query2 = null;
|
||||
|
||||
if (parts.Length > 1)
|
||||
{
|
||||
path = parts[0];
|
||||
query = string.Join('?', parts.Skip(1));
|
||||
}
|
||||
|
||||
builder.Path += path;
|
||||
|
||||
if (sections.Count > 1)
|
||||
{
|
||||
if (!requiresBody || !File.Exists(sections[1]))
|
||||
{
|
||||
if (sections[1].Length > 0)
|
||||
{
|
||||
if (sections[1][0] != '/')
|
||||
{
|
||||
string argPath = sections[1];
|
||||
if (builder.Path.Length > 0 && builder.Path[builder.Path.Length - 1] != '/')
|
||||
{
|
||||
argPath = "/" + argPath;
|
||||
}
|
||||
|
||||
int queryIndex = argPath.IndexOf('?');
|
||||
path = argPath;
|
||||
|
||||
if (queryIndex > -1)
|
||||
{
|
||||
query2 = argPath.Substring(queryIndex + 1);
|
||||
path = argPath.Substring(0, queryIndex);
|
||||
}
|
||||
|
||||
builder.Path += path;
|
||||
}
|
||||
else
|
||||
{
|
||||
int queryIndex = sections[1].IndexOf('?');
|
||||
path = sections[1];
|
||||
|
||||
if (queryIndex > -1)
|
||||
{
|
||||
query2 = sections[1].Substring(queryIndex + 1);
|
||||
path = sections[1].Substring(0, queryIndex);
|
||||
}
|
||||
|
||||
builder.Path = path;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
int queryIndex = sections[1].IndexOf('?');
|
||||
path = sections[1];
|
||||
|
||||
if (queryIndex > -1)
|
||||
{
|
||||
query2 = sections[1].Substring(queryIndex + 1);
|
||||
path = sections[1].Substring(0, queryIndex);
|
||||
}
|
||||
|
||||
builder.Path += path;
|
||||
}
|
||||
|
||||
filePathIndex = 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (query != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(builder.Query))
|
||||
{
|
||||
query = "&" + query;
|
||||
}
|
||||
|
||||
builder.Query += query;
|
||||
}
|
||||
|
||||
if (query2 != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(builder.Query))
|
||||
{
|
||||
query2 = "&" + query2;
|
||||
}
|
||||
|
||||
builder.Query += query2;
|
||||
}
|
||||
|
||||
return builder.Uri;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.HttpRepl
|
||||
{
|
||||
public interface IDirectoryStructure
|
||||
{
|
||||
IEnumerable<string> DirectoryNames { get; }
|
||||
|
||||
IDirectoryStructure Parent { get; }
|
||||
|
||||
IDirectoryStructure GetChildDirectory(string name);
|
||||
|
||||
IRequestInfo RequestInfo { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.HttpRepl
|
||||
{
|
||||
public interface IRequestInfo
|
||||
{
|
||||
IReadOnlyDictionary<string, IReadOnlyList<string>> ContentTypesByMethod { get; }
|
||||
|
||||
IReadOnlyList<string> Methods { get; }
|
||||
|
||||
string GetRequestBodyForContentType(ref string contentType, string method);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<PackAsTool>true</PackAsTool>
|
||||
<AssemblyName>dotnet-httprepl</AssemblyName>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Description>Command line tool to for making HTTP calls and viewing their results.</Description>
|
||||
<PackageTags>dotnet;http;httprepl</PackageTags>
|
||||
<!-- This is a requirement for Microsoft tool packages only. -->
|
||||
<PackAsToolShimRuntimeIdentifiers>win-x64;win-x86</PackAsToolShimRuntimeIdentifiers>
|
||||
|
||||
<!-- Temporarily disables producing this project as a package while we work through some RTM-blocking bugs. -->
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="$(MicrosoftWebApiClientPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.Repl\Microsoft.Repl.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<SignedPackageFile Include="$(PublishDir)Microsoft.Repl.dll" PackagePath="tools/$(TargetFramework)/any/Microsoft.Repl.dll" Certificate="$(AssemblySigningCertName)" />
|
||||
<SignedPackageFile Include="$(PublishDir)Newtonsoft.Json.dll" PackagePath="tools/$(TargetFramework)/any/Newtonsoft.Json.dll" Certificate="$(AssemblySigning3rdPartyCertName)" />
|
||||
<SignedPackageFile Include="$(PublishDir)Newtonsoft.Json.Bson.dll" PackagePath="tools/$(TargetFramework)/any/Newtonsoft.Json.Bson.dll" Certificate="$(AssemblySigning3rdPartyCertName)" />
|
||||
<ExcludePackageFileFromSigning Include="$(PublishDir)System.Net.Http.Formatting.dll" PackagePath="tools/$(TargetFramework)/any/System.Net.Http.Formatting.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class Either<TOption1, TOption2>
|
||||
{
|
||||
public Either(TOption1 option1)
|
||||
{
|
||||
Option1 = option1;
|
||||
IsOption1 = true;
|
||||
}
|
||||
|
||||
public Either(TOption2 option2)
|
||||
{
|
||||
Option2 = option2;
|
||||
IsOption1 = false;
|
||||
}
|
||||
|
||||
public bool IsOption1 { get; }
|
||||
|
||||
public TOption1 Option1 { get; }
|
||||
|
||||
public TOption2 Option2 { get; }
|
||||
|
||||
public static implicit operator Either<TOption1, TOption2>(TOption1 value)
|
||||
{
|
||||
return new Either<TOption1, TOption2>(value);
|
||||
}
|
||||
|
||||
public static implicit operator Either<TOption1, TOption2>(TOption2 value)
|
||||
{
|
||||
return new Either<TOption1, TOption2>(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class EitherConverter<TOption1, TOption2> : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(TOption1).IsAssignableFrom(objectType) || typeof(TOption2).IsAssignableFrom(objectType) || typeof(EitherConverter<TOption1, TOption2>) == objectType;
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
try
|
||||
{
|
||||
TOption1 option1 = serializer.Deserialize<TOption1>(reader);
|
||||
return new Either<TOption1, TOption2>(option1);
|
||||
}
|
||||
catch
|
||||
{
|
||||
TOption2 option2 = serializer.Deserialize<TOption2>(reader);
|
||||
return new Either<TOption1, TOption2>(option2);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class EndpointMetadata
|
||||
{
|
||||
public EndpointMetadata(string path, IReadOnlyDictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>> requestsByMethodAndContentType)
|
||||
{
|
||||
Path = path;
|
||||
AvailableRequests = requestsByMethodAndContentType ?? new Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>>();
|
||||
}
|
||||
|
||||
public string Path { get; }
|
||||
|
||||
public IReadOnlyDictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>> AvailableRequests { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class EndpointMetadataReader
|
||||
{
|
||||
private readonly List<IEndpointMetadataReader> _readers = new List<IEndpointMetadataReader>
|
||||
{
|
||||
new OpenApiV3EndpointMetadataReader(),
|
||||
new SwaggerV2EndpointMetadataReader(),
|
||||
new SwaggerV1EndpointMetadataReader()
|
||||
};
|
||||
|
||||
public void RegisterReader(IEndpointMetadataReader reader)
|
||||
{
|
||||
_readers.Add(reader);
|
||||
}
|
||||
|
||||
public IEnumerable<EndpointMetadata> Read(JObject document)
|
||||
{
|
||||
foreach (IEndpointMetadataReader reader in _readers)
|
||||
{
|
||||
if (reader.CanHandle(document))
|
||||
{
|
||||
IEnumerable<EndpointMetadata> result = reader.ReadMetadata(document);
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public interface IEndpointMetadataReader
|
||||
{
|
||||
bool CanHandle(JObject document);
|
||||
|
||||
IEnumerable<EndpointMetadata> ReadMetadata(JObject document);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class OpenApiV3EndpointMetadataReader : IEndpointMetadataReader
|
||||
{
|
||||
public bool CanHandle(JObject document)
|
||||
{
|
||||
return (document["openapi"]?.ToString() ?? "").StartsWith("3.", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public IEnumerable<EndpointMetadata> ReadMetadata(JObject document)
|
||||
{
|
||||
List<EndpointMetadata> metadata = new List<EndpointMetadata>();
|
||||
|
||||
if (document["paths"] is JObject paths)
|
||||
{
|
||||
foreach (JProperty path in paths.Properties())
|
||||
{
|
||||
if (!(path.Value is JObject pathBody))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>> requestMethods = new Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (JProperty method in pathBody.Properties())
|
||||
{
|
||||
List<Parameter> parameters = new List<Parameter>();
|
||||
|
||||
if (method.Value is JObject methodBody)
|
||||
{
|
||||
if (methodBody["parameters"] is JArray parametersArray)
|
||||
{
|
||||
foreach (JObject parameterObj in parametersArray.OfType<JObject>())
|
||||
{
|
||||
Parameter p = parameterObj.ToObject<Parameter>();
|
||||
p.Location = parameterObj["in"]?.ToString();
|
||||
|
||||
if (!(parameterObj["schema"] is JObject schemaObject))
|
||||
{
|
||||
schemaObject = null;
|
||||
}
|
||||
|
||||
p.Schema = schemaObject?.ToObject<Schema>() ?? parameterObj.ToObject<Schema>();
|
||||
parameters.Add(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (methodBody["requestBody"] is JObject bodyObject)
|
||||
{
|
||||
if (!(bodyObject["content"] is JObject contentTypeLookup))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (JProperty contentTypeEntry in contentTypeLookup.Properties())
|
||||
{
|
||||
List<Parameter> parametersByContentType = new List<Parameter>(parameters);
|
||||
Parameter p = bodyObject.ToObject<Parameter>();
|
||||
p.Location = "body";
|
||||
p.IsRequired = bodyObject["required"]?.ToObject<bool>() ?? false;
|
||||
|
||||
if (!(bodyObject["schema"] is JObject schemaObject))
|
||||
{
|
||||
schemaObject = null;
|
||||
}
|
||||
|
||||
p.Schema = schemaObject?.ToObject<Schema>() ?? bodyObject.ToObject<Schema>();
|
||||
parametersByContentType.Add(p);
|
||||
|
||||
Dictionary<string, IReadOnlyList<Parameter>> bucketByMethod;
|
||||
if (!requestMethods.TryGetValue(method.Name, out IReadOnlyDictionary<string, IReadOnlyList<Parameter>> bucketByMethodRaw))
|
||||
{
|
||||
requestMethods[method.Name] = bucketByMethodRaw = new Dictionary<string, IReadOnlyList<Parameter>>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "", parametersByContentType }
|
||||
};
|
||||
}
|
||||
|
||||
bucketByMethod = (Dictionary<string, IReadOnlyList<Parameter>>)bucketByMethodRaw;
|
||||
bucketByMethod[contentTypeEntry.Name] = parametersByContentType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
metadata.Add(new EndpointMetadata(path.Name, requestMethods));
|
||||
}
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class Parameter
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Location { get; set; }
|
||||
|
||||
public bool IsRequired { get; set; }
|
||||
|
||||
public Schema Schema { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,150 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public static class PointerUtil
|
||||
{
|
||||
public static Task<JToken> ResolvePointersAsync(Uri loadLocation, JToken root, HttpClient client)
|
||||
{
|
||||
return ResolvePointersAsync(loadLocation, root, root, client);
|
||||
}
|
||||
|
||||
private static async Task<JToken> ResolvePointersAsync(Uri loadLocation, JToken root, JToken toResolve, HttpClient client)
|
||||
{
|
||||
JToken cursor = root;
|
||||
|
||||
if (toResolve is JArray arr)
|
||||
{
|
||||
for (int i = 0; i < arr.Count; ++i)
|
||||
{
|
||||
arr[i] = await ResolvePointersAsync(loadLocation, root, arr[i], client).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else if (toResolve is JObject obj)
|
||||
{
|
||||
if (obj["$ref"] is JValue refVal && refVal.Type == JTokenType.String)
|
||||
{
|
||||
if (!Uri.TryCreate((string)refVal.Value, UriKind.RelativeOrAbsolute, out Uri loadTarget))
|
||||
{
|
||||
//TODO: Error resolving pointer (pointer must be a valid URI)
|
||||
return new JValue((object)null);
|
||||
}
|
||||
|
||||
if (!loadTarget.IsAbsoluteUri)
|
||||
{
|
||||
if (!Uri.TryCreate(loadLocation, loadTarget, out loadTarget))
|
||||
{
|
||||
//TODO: Error resolving pointer (could not combine with base path)
|
||||
return new JValue((object)null);
|
||||
}
|
||||
}
|
||||
|
||||
//Check to see if we're changing source documents, if we are, get it
|
||||
if (!string.Equals(loadLocation.Host, loadTarget.Host, StringComparison.OrdinalIgnoreCase) || !string.Equals(loadLocation.AbsolutePath, loadTarget.AbsolutePath, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
HttpResponseMessage responseMessage = await client.GetAsync(loadTarget).ConfigureAwait(false);
|
||||
|
||||
if (!responseMessage.IsSuccessStatusCode)
|
||||
{
|
||||
//TODO: Error resolving pointer (could not get referenced document)
|
||||
return new JValue((object)null);
|
||||
}
|
||||
|
||||
string responseString = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
JToken newRoot;
|
||||
|
||||
try
|
||||
{
|
||||
newRoot = JToken.Parse(responseString);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//TODO: Error resolving pointer (referenced document is not valid JSON)
|
||||
return new JValue((object)null);
|
||||
}
|
||||
|
||||
cursor = await ResolvePointersAsync(loadTarget, newRoot, newRoot, client).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
//We're in the right document, grab the bookmark (fragment) of the URI and get the element at that path
|
||||
string fragment = loadTarget.Fragment;
|
||||
|
||||
if (fragment.StartsWith('#'))
|
||||
{
|
||||
fragment = fragment.Substring(1);
|
||||
}
|
||||
|
||||
string[] parts = fragment.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
for (int i = 0; i < parts.Length; ++i)
|
||||
{
|
||||
if (cursor is JArray ca)
|
||||
{
|
||||
if (!int.TryParse(parts[i], NumberStyles.Integer, CultureInfo.InvariantCulture, out int index))
|
||||
{
|
||||
//TODO: Error resolving pointer, array index is non-integral
|
||||
return new JValue((object)null);
|
||||
}
|
||||
|
||||
if (index < 0 || index >= ca.Count)
|
||||
{
|
||||
//TODO: Error resolving pointer, array index is out of bounds
|
||||
return new JValue((object)null);
|
||||
}
|
||||
|
||||
JToken val = ca[index];
|
||||
if (val is JObject vo && vo.TryGetValue("$ref", out JToken vor) && vor is JValue vorv && vorv.Type == JTokenType.String)
|
||||
{
|
||||
cursor = await ResolvePointersAsync(loadLocation, root, val, client).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor = val;
|
||||
}
|
||||
}
|
||||
else if (cursor is JObject co)
|
||||
{
|
||||
if (!co.TryGetValue(parts[i], out JToken val))
|
||||
{
|
||||
//TODO: Error resolving pointer, no such property on object
|
||||
return new JValue((object)null);
|
||||
}
|
||||
|
||||
if (val is JObject vo && vo.TryGetValue("$ref", out JToken vor) && vor is JValue vorv && vorv.Type == JTokenType.String)
|
||||
{
|
||||
cursor = await ResolvePointersAsync(loadLocation, root, val, client).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor = val;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: Error resolving pointer, cannot index into literal
|
||||
return new JValue((object)null);
|
||||
}
|
||||
}
|
||||
|
||||
cursor = await ResolvePointersAsync(loadLocation, root, cursor, client);
|
||||
return cursor.DeepClone();
|
||||
}
|
||||
|
||||
foreach (JProperty property in obj.Properties().ToList())
|
||||
{
|
||||
obj[property.Name] = await ResolvePointersAsync(loadLocation, root, property.Value, client).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
return toResolve;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class Schema
|
||||
{
|
||||
public void PrepareForUsage(JToken document)
|
||||
{
|
||||
AdditionalProperties?.Option1?.PrepareForUsage(document);
|
||||
|
||||
if (AllOf != null)
|
||||
{
|
||||
for (int i = 0; i < AllOf.Length; ++i)
|
||||
{
|
||||
AllOf[i].PrepareForUsage(document);
|
||||
}
|
||||
}
|
||||
|
||||
if (AnyOf != null)
|
||||
{
|
||||
for (int i = 0; i < AnyOf.Length; ++i)
|
||||
{
|
||||
AnyOf[i].PrepareForUsage(document);
|
||||
}
|
||||
}
|
||||
|
||||
if (OneOf != null)
|
||||
{
|
||||
for (int i = 0; i < OneOf.Length; ++i)
|
||||
{
|
||||
OneOf[i].PrepareForUsage(document);
|
||||
}
|
||||
}
|
||||
|
||||
if (Properties != null)
|
||||
{
|
||||
IReadOnlyList<string> keys = Properties.Keys.ToList();
|
||||
for (int i = 0; i < keys.Count; ++i)
|
||||
{
|
||||
Properties[keys[i]]?.PrepareForUsage(document);
|
||||
}
|
||||
}
|
||||
|
||||
Items?.PrepareForUsage(document);
|
||||
Not?.PrepareForUsage(document);
|
||||
|
||||
if (Required?.Option1 != null)
|
||||
{
|
||||
if (Properties != null)
|
||||
{
|
||||
foreach (string propertyName in Required.Option1)
|
||||
{
|
||||
if (Properties.TryGetValue(propertyName, out Schema value))
|
||||
{
|
||||
value.Required = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Required = false;
|
||||
}
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(EitherConverter<Schema, bool>))]
|
||||
public Either<Schema, bool> AdditionalProperties { get; set; }
|
||||
|
||||
public Schema[] AllOf { get; set; }
|
||||
|
||||
public Schema[] AnyOf { get; set; }
|
||||
|
||||
public object Default { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
public object[] Enum { get; set; }
|
||||
|
||||
public object Example { get; set; }
|
||||
|
||||
public bool ExclusiveMaximum { get; set; }
|
||||
|
||||
public bool ExclusiveMinimum { get; set; }
|
||||
|
||||
public string Format { get; set; }
|
||||
|
||||
public Schema Items { get; set; }
|
||||
|
||||
public double? Maximum { get; set; }
|
||||
|
||||
public double? Minimum { get; set; }
|
||||
|
||||
public int? MaxItems { get; set; }
|
||||
|
||||
public int? MinItems { get; set; }
|
||||
|
||||
public int? MaxLength { get; set; }
|
||||
|
||||
public int? MinLength { get; set; }
|
||||
|
||||
public int? MaxProperties { get; set; }
|
||||
|
||||
public int? MinProperties { get; set; }
|
||||
|
||||
public double? MultipleOf { get; set; }
|
||||
|
||||
public Schema Not { get; set; }
|
||||
|
||||
public Schema[] OneOf { get; set; }
|
||||
|
||||
public string Pattern { get; set; }
|
||||
|
||||
public Dictionary<string, Schema> Properties { get; set; }
|
||||
|
||||
[JsonConverter(typeof(EitherConverter<string[], bool>))]
|
||||
public Either<string[], bool> Required { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
|
||||
public string Type { get; set; }
|
||||
|
||||
public bool UniqueItems { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class SwaggerV1EndpointMetadataReader : IEndpointMetadataReader
|
||||
{
|
||||
public bool CanHandle(JObject document)
|
||||
{
|
||||
return (document["swaggerVersion"]?.ToString() ?? "").StartsWith("1.", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public IEnumerable<EndpointMetadata> ReadMetadata(JObject document)
|
||||
{
|
||||
List<EndpointMetadata> metadata = new List<EndpointMetadata>();
|
||||
|
||||
if (!(document["consumes"] is JArray globalConsumes))
|
||||
{
|
||||
globalConsumes = new JArray();
|
||||
}
|
||||
|
||||
if (document["apis"] is JObject obj)
|
||||
{
|
||||
foreach (JProperty property in obj.Properties())
|
||||
{
|
||||
string path = obj["path"]?.ToString();
|
||||
|
||||
if (path is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>> requestMethods = new Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>>(StringComparer.Ordinal);
|
||||
|
||||
if (obj["operations"] is JArray operations)
|
||||
{
|
||||
foreach (JObject operationObject in operations.OfType<JObject>())
|
||||
{
|
||||
string method = operationObject["method"]?.ToString();
|
||||
List<Parameter> parameters = new List<Parameter>();
|
||||
|
||||
if (operationObject["parameters"] is JArray parametersArray)
|
||||
{
|
||||
foreach (JObject parameterObj in parametersArray.OfType<JObject>())
|
||||
{
|
||||
Parameter p = parameterObj.ToObject<Parameter>();
|
||||
p.Location = parameterObj["paramType"]?.ToString();
|
||||
p.IsRequired = parameterObj["required"]?.ToObject<bool>() ?? false;
|
||||
|
||||
string type = parameterObj["type"]?.ToString();
|
||||
|
||||
if (type is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (type.ToUpperInvariant())
|
||||
{
|
||||
case "INTEGER":
|
||||
case "NUMBER":
|
||||
case "STRING":
|
||||
case "BOOLEAN":
|
||||
p.Schema = new Schema { Type = type };
|
||||
break;
|
||||
case "FILE":
|
||||
break;
|
||||
default:
|
||||
if (document["models"]?[type] is JObject schemaObject)
|
||||
{
|
||||
//TODO: Handle subtypes (https://github.com/OAI/OpenAPI-Specification/blob/master/versions/1.2.md#527-model-object)
|
||||
p.Schema = schemaObject.ToObject<Schema>();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
parameters.Add(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(operationObject["consumes"] is JArray consumes))
|
||||
{
|
||||
consumes = globalConsumes;
|
||||
}
|
||||
|
||||
Dictionary<string, IReadOnlyList<Parameter>> parametersByContentType = new Dictionary<string, IReadOnlyList<Parameter>>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "", parameters }
|
||||
};
|
||||
|
||||
foreach (JValue value in consumes.OfType<JValue>().Where(x => x.Type == JTokenType.String))
|
||||
{
|
||||
parametersByContentType[value.ToString()] = parameters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
metadata.Add(new EndpointMetadata(path, requestMethods));
|
||||
}
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.HttpRepl.OpenApi
|
||||
{
|
||||
public class SwaggerV2EndpointMetadataReader : IEndpointMetadataReader
|
||||
{
|
||||
public bool CanHandle(JObject document)
|
||||
{
|
||||
return (document["swagger"]?.ToString() ?? "").StartsWith("2.", StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public IEnumerable<EndpointMetadata> ReadMetadata(JObject document)
|
||||
{
|
||||
List<EndpointMetadata> metadata = new List<EndpointMetadata>();
|
||||
|
||||
if (!(document["consumes"] is JArray globalConsumes))
|
||||
{
|
||||
globalConsumes = new JArray();
|
||||
}
|
||||
|
||||
if (document["paths"] is JObject obj)
|
||||
{
|
||||
foreach (JProperty property in obj.Properties())
|
||||
{
|
||||
if (!(property.Value is JObject requestMethodInfos))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>> requestMethods = new Dictionary<string, IReadOnlyDictionary<string, IReadOnlyList<Parameter>>>(StringComparer.Ordinal);
|
||||
|
||||
foreach (JProperty methodInfo in requestMethodInfos.Properties())
|
||||
{
|
||||
List<Parameter> parameters = new List<Parameter>();
|
||||
|
||||
if (methodInfo.Value is JObject methodInfoDescription)
|
||||
{
|
||||
if (methodInfoDescription["parameters"] is JArray parametersArray)
|
||||
{
|
||||
foreach (JObject parameterObj in parametersArray.OfType<JObject>())
|
||||
{
|
||||
//TODO: Resolve refs here
|
||||
|
||||
Parameter p = parameterObj.ToObject<Parameter>();
|
||||
p.Location = parameterObj["in"]?.ToString();
|
||||
p.IsRequired = parameterObj["required"]?.ToObject<bool>() ?? false;
|
||||
|
||||
if (!(parameterObj["schema"] is JObject schemaObject))
|
||||
{
|
||||
schemaObject = null;
|
||||
}
|
||||
|
||||
p.Schema = schemaObject?.ToObject<Schema>() ?? parameterObj.ToObject<Schema>();
|
||||
parameters.Add(p);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(methodInfoDescription["consumes"] is JArray consumes))
|
||||
{
|
||||
consumes = globalConsumes;
|
||||
}
|
||||
|
||||
Dictionary<string, IReadOnlyList<Parameter>> parametersByContentType = new Dictionary<string, IReadOnlyList<Parameter>>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "", parameters }
|
||||
};
|
||||
|
||||
foreach (JValue value in consumes.OfType<JValue>().Where(x => x.Type == JTokenType.String))
|
||||
{
|
||||
parametersByContentType[value.ToString()] = parameters;
|
||||
}
|
||||
|
||||
requestMethods[methodInfo.Name] = parametersByContentType;
|
||||
}
|
||||
}
|
||||
|
||||
metadata.Add(new EndpointMetadata(property.Name, requestMethods));
|
||||
}
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
|
||||
namespace Microsoft.HttpRepl.Preferences
|
||||
{
|
||||
public interface IJsonConfig
|
||||
{
|
||||
int IndentSize { get; }
|
||||
|
||||
AllowedColors DefaultColor { get; }
|
||||
|
||||
AllowedColors ArrayBraceColor { get; }
|
||||
|
||||
AllowedColors ObjectBraceColor { get; }
|
||||
|
||||
AllowedColors CommaColor { get; }
|
||||
|
||||
AllowedColors NameColor { get; }
|
||||
|
||||
AllowedColors NameSeparatorColor { get; }
|
||||
|
||||
AllowedColors BoolColor { get; }
|
||||
|
||||
AllowedColors NumericColor { get; }
|
||||
|
||||
AllowedColors StringColor { get; }
|
||||
|
||||
AllowedColors NullColor { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
|
||||
namespace Microsoft.HttpRepl.Preferences
|
||||
{
|
||||
public class JsonConfig : IJsonConfig
|
||||
{
|
||||
private readonly HttpState _state;
|
||||
|
||||
public int IndentSize => _state.GetIntPreference(WellKnownPreference.JsonIndentSize, 2);
|
||||
|
||||
public AllowedColors DefaultColor => _state.GetColorPreference(WellKnownPreference.JsonColor);
|
||||
|
||||
private AllowedColors DefaultBraceColor => _state.GetColorPreference(WellKnownPreference.JsonBraceColor, DefaultSyntaxColor);
|
||||
|
||||
private AllowedColors DefaultSyntaxColor => _state.GetColorPreference(WellKnownPreference.JsonSyntaxColor, DefaultColor);
|
||||
|
||||
private AllowedColors DefaultLiteralColor => _state.GetColorPreference(WellKnownPreference.JsonLiteralColor, DefaultColor);
|
||||
|
||||
public AllowedColors ArrayBraceColor => _state.GetColorPreference(WellKnownPreference.JsonArrayBraceColor, DefaultBraceColor);
|
||||
|
||||
public AllowedColors ObjectBraceColor => _state.GetColorPreference(WellKnownPreference.JsonObjectBraceColor, DefaultBraceColor);
|
||||
|
||||
public AllowedColors CommaColor => _state.GetColorPreference(WellKnownPreference.JsonCommaColor, DefaultSyntaxColor);
|
||||
|
||||
public AllowedColors NameColor => _state.GetColorPreference(WellKnownPreference.JsonNameColor, StringColor);
|
||||
|
||||
public AllowedColors NameSeparatorColor => _state.GetColorPreference(WellKnownPreference.JsonNameSeparatorColor, DefaultSyntaxColor);
|
||||
|
||||
public AllowedColors BoolColor => _state.GetColorPreference(WellKnownPreference.JsonBoolColor, DefaultLiteralColor);
|
||||
|
||||
public AllowedColors NumericColor => _state.GetColorPreference(WellKnownPreference.JsonNumericColor, DefaultLiteralColor);
|
||||
|
||||
public AllowedColors StringColor => _state.GetColorPreference(WellKnownPreference.JsonStringColor, DefaultLiteralColor);
|
||||
|
||||
public AllowedColors NullColor => _state.GetColorPreference(WellKnownPreference.JsonNullColor, DefaultLiteralColor);
|
||||
|
||||
public JsonConfig(HttpState state)
|
||||
{
|
||||
_state = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
|
||||
namespace Microsoft.HttpRepl.Preferences
|
||||
{
|
||||
public class RequestConfig : RequestOrResponseConfig
|
||||
{
|
||||
public RequestConfig(HttpState state)
|
||||
: base(state)
|
||||
{
|
||||
}
|
||||
|
||||
public override AllowedColors BodyColor => State.GetColorPreference(WellKnownPreference.RequestBodyColor, base.BodyColor);
|
||||
|
||||
public override AllowedColors SchemeColor => State.GetColorPreference(WellKnownPreference.RequestSchemeColor, base.SchemeColor);
|
||||
|
||||
public override AllowedColors HeaderKeyColor => State.GetColorPreference(WellKnownPreference.RequestHeaderKeyColor, base.HeaderKeyColor);
|
||||
|
||||
public override AllowedColors HeaderSeparatorColor => State.GetColorPreference(WellKnownPreference.RequestHeaderSeparatorColor, base.HeaderSeparatorColor);
|
||||
|
||||
public override AllowedColors HeaderValueSeparatorColor => State.GetColorPreference(WellKnownPreference.RequestHeaderValueSeparatorColor, base.HeaderValueSeparatorColor);
|
||||
|
||||
public override AllowedColors HeaderValueColor => State.GetColorPreference(WellKnownPreference.RequestHeaderValueColor, base.HeaderValueColor);
|
||||
|
||||
public override AllowedColors HeaderColor => State.GetColorPreference(WellKnownPreference.RequestHeaderColor, base.HeaderColor);
|
||||
|
||||
public override AllowedColors GeneralColor => State.GetColorPreference(WellKnownPreference.RequestColor, base.GeneralColor);
|
||||
|
||||
public override AllowedColors ProtocolColor => State.GetColorPreference(WellKnownPreference.RequestProtocolColor, base.ProtocolColor);
|
||||
|
||||
public override AllowedColors ProtocolNameColor => State.GetColorPreference(WellKnownPreference.RequestProtocolNameColor, base.ProtocolNameColor);
|
||||
|
||||
public override AllowedColors ProtocolVersionColor => State.GetColorPreference(WellKnownPreference.RequestProtocolVersionColor, base.ProtocolVersionColor);
|
||||
|
||||
public override AllowedColors ProtocolSeparatorColor => State.GetColorPreference(WellKnownPreference.RequestProtocolSeparatorColor, base.ProtocolSeparatorColor);
|
||||
|
||||
public override AllowedColors StatusColor => State.GetColorPreference(WellKnownPreference.RequestStatusColor, base.StatusColor);
|
||||
|
||||
public override AllowedColors StatusCodeColor => State.GetColorPreference(WellKnownPreference.RequestStatusCodeColor, base.StatusCodeColor);
|
||||
|
||||
public override AllowedColors StatusReasonPhraseColor => State.GetColorPreference(WellKnownPreference.RequestStatusReaseonPhraseColor, base.StatusReasonPhraseColor);
|
||||
|
||||
public AllowedColors MethodColor => State.GetColorPreference(WellKnownPreference.RequestMethodColor, GeneralColor);
|
||||
|
||||
public AllowedColors AddressColor => State.GetColorPreference(WellKnownPreference.RequestAddressColor, GeneralColor);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.Repl.ConsoleHandling;
|
||||
|
||||
namespace Microsoft.HttpRepl.Preferences
|
||||
{
|
||||
public abstract class RequestOrResponseConfig
|
||||
{
|
||||
protected HttpState State { get; }
|
||||
|
||||
protected RequestOrResponseConfig(HttpState state)
|
||||
{
|
||||
State = state;
|
||||
}
|
||||
|
||||
public virtual AllowedColors BodyColor => State.GetColorPreference(WellKnownPreference.BodyColor, GeneralColor);
|
||||
|
||||
public virtual AllowedColors SchemeColor => State.GetColorPreference(WellKnownPreference.SchemeColor, GeneralColor);
|
||||
|
||||
public virtual AllowedColors HeaderKeyColor => State.GetColorPreference(WellKnownPreference.HeaderKeyColor, HeaderColor);
|
||||
|
||||
public virtual AllowedColors HeaderSeparatorColor => State.GetColorPreference(WellKnownPreference.HeaderSeparatorColor, HeaderColor);
|
||||
|
||||
public virtual AllowedColors HeaderValueSeparatorColor => State.GetColorPreference(WellKnownPreference.HeaderValueSeparatorColor, HeaderSeparatorColor);
|
||||
|
||||
public virtual AllowedColors HeaderValueColor => State.GetColorPreference(WellKnownPreference.HeaderValueColor, HeaderColor);
|
||||
|
||||
public virtual AllowedColors HeaderColor => State.GetColorPreference(WellKnownPreference.HeaderColor, GeneralColor);
|
||||
|
||||
public virtual AllowedColors GeneralColor => State.GetColorPreference(WellKnownPreference.RequestOrResponseColor);
|
||||
|
||||
public virtual AllowedColors ProtocolColor => State.GetColorPreference(WellKnownPreference.ProtocolColor, GeneralColor);
|
||||
|
||||
public virtual AllowedColors ProtocolNameColor => State.GetColorPreference(WellKnownPreference.ProtocolNameColor, ProtocolColor);
|
||||
|
||||
public virtual AllowedColors ProtocolVersionColor => State.GetColorPreference(WellKnownPreference.ProtocolVersionColor, ProtocolColor);
|
||||
|
||||
public virtual AllowedColors ProtocolSeparatorColor => State.GetColorPreference(WellKnownPreference.ProtocolSeparatorColor, ProtocolColor);
|
||||
|
||||
public virtual AllowedColors StatusColor => State.GetColorPreference(WellKnownPreference.StatusColor, GeneralColor);
|
||||
|
||||
public virtual AllowedColors StatusCodeColor => State.GetColorPreference(WellKnownPreference.StatusCodeColor, StatusColor);
|
||||
|
||||
public virtual AllowedColors StatusReasonPhraseColor => State.GetColorPreference(WellKnownPreference.StatusReaseonPhraseColor, StatusColor);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue