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:
Nate McMaster 2018-11-14 14:10:28 -08:00
commit 401fd68985
No known key found for this signature in database
GPG Key ID: A778D9601BD78810
288 changed files with 211 additions and 11760 deletions

View File

@ -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

View File

@ -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

52
.gitattributes vendored
View File

@ -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

37
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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.

View File

@ -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>

View File

@ -1,40 +0,0 @@
DotNetTools
===========
[![Travis build status](https://img.shields.io/travis/aspnet/DotNetTools.svg?label=travis-ci&branch=dev&style=flat-square)](https://travis-ci.org/aspnet/DotNetTools/branches)
[![AppVeyor build status](https://img.shields.io/appveyor/ci/aspnetci/DotNetTools/dev.svg?label=appveyor&style=flat-square)](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
```

View File

@ -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"

View File

@ -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 "$@"

Binary file not shown.

View File

@ -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>

View File

@ -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="&quot;$(VisualStudioMSBuildx86Path)&quot; @&quot;$(VSIXResponseFilePath)&quot;"
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="&quot;$(VisualStudioMSBuildx86Path)&quot; @&quot;$(VSIXResponseFilePath)&quot;"
Condition="'$(VisualStudioMSBuildx86Path)' != ''" />
</Target>
</Project>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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"
]
}
}

View File

@ -1,2 +0,0 @@
version:2.2.0-preview2-20181026.4
commithash:f05a283e6c1eb66ef29a32526f75f8b567a986c9

View File

@ -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"
]
}
}
}

View File

@ -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
View File

@ -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
View File

@ -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" "$@"

View File

@ -1,2 +0,0 @@
<!-- Intentionally empty to isolate the samples. -->
<Project />

View File

@ -1,2 +0,0 @@
<!-- Intentionally empty to isolate the samples. -->
<Project />

View File

@ -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>

View File

@ -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.

View File

@ -1,8 +0,0 @@
{
"name": "any-command",
"version": "0.0.0",
"private": true,
"scripts": {
"custom": "node say-hello.js"
}
}

View File

@ -1 +0,0 @@
console.log("Hello from Javascript");

View File

@ -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.

View File

@ -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();
}
}
}

View File

@ -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.

View File

@ -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>

View File

@ -1 +0,0 @@
document.title = "My awesome website";

View File

@ -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.

View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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>

View File

@ -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>

View File

@ -1,7 +0,0 @@
<Project>
<Import Project="..\Directory.Build.props" />
<ItemGroup>
<PackageReference Include="Internal.AspNetCore.Sdk" PrivateAssets="All" Version="$(InternalAspNetCoreSdkPackageVersion)" />
</ItemGroup>
</Project>

View File

@ -1,7 +0,0 @@
<Project>
<Import Project="..\Directory.Build.targets" />
<Target Name="CleanPublishDir" AfterTargets="CoreClean">
<RemoveDir Directories="$(PublishDir)" />
</Target>
</Project>

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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";
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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";
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}
}
}

View File

@ -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; }
}
}

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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; }
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}
}

View File

@ -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; }
}
}

View File

@ -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;
}
}
}

View File

@ -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; }
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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; }
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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