Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
433c827d
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
433c827d
编写于
3月 01, 2016
作者:
J
Jared Parsons
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #9312 from jaredpar/cache
Use web storage for test caching layer
上级
6eeb7637
66f56bc2
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
295 addition
and
23 deletion
+295
-23
BuildAndTest.proj
BuildAndTest.proj
+1
-1
src/Tools/Source/RunTests/Cache/CachingTestExecutor.cs
src/Tools/Source/RunTests/Cache/CachingTestExecutor.cs
+16
-13
src/Tools/Source/RunTests/Cache/IDataStorage.cs
src/Tools/Source/RunTests/Cache/IDataStorage.cs
+6
-3
src/Tools/Source/RunTests/Cache/LocalDataStorage.cs
src/Tools/Source/RunTests/Cache/LocalDataStorage.cs
+22
-4
src/Tools/Source/RunTests/Cache/WebDataStorage.cs
src/Tools/Source/RunTests/Cache/WebDataStorage.cs
+87
-0
src/Tools/Source/RunTests/Program.cs
src/Tools/Source/RunTests/Program.cs
+12
-1
src/Tools/Source/RunTests/RunTests.csproj
src/Tools/Source/RunTests/RunTests.csproj
+9
-1
src/Tools/Source/RunTests/project.json
src/Tools/Source/RunTests/project.json
+13
-0
src/Tools/Source/RunTests/project.lock.json
src/Tools/Source/RunTests/project.lock.json
+129
-0
未找到文件。
BuildAndTest.proj
浏览文件 @
433c827d
...
...
@@ -96,7 +96,7 @@
<Exec Command="$(CoreClrTestDirectory)\CoreRun.exe $(CoreClrTestDirectory)\xunit.console.netcore.exe @(CoreTestAssemblies, ' ') -parallel all -xml $(CoreClrTestDirectory)\xUnitResults\TestResults.xml" />
<Exec Command="Binaries\$(Configuration)\RunTests.exe $(NuGetPackageRoot)\xunit.runner.console\$(XunitVersion)\tools $(RunTestArgs) @(TestAssemblies, ' ')" />
<Exec Command="Binaries\$(Configuration)\RunTests
\RunTests
.exe $(NuGetPackageRoot)\xunit.runner.console\$(XunitVersion)\tools $(RunTestArgs) @(TestAssemblies, ' ')" />
</Target>
...
...
src/Tools/Source/RunTests/Cache/CachingTestExecutor.cs
浏览文件 @
433c827d
...
...
@@ -36,21 +36,23 @@ public async Task<TestResult> RunTestAsync(string assemblyPath, CancellationToke
builder
.
AppendLine
(
"==="
);
Logger
.
Log
(
builder
.
ToString
());
TestResult
testResult
;
CachedTestResult
cachedTestResult
;
if
(!
_dataStorage
.
TryGetCachedTestResult
(
contentFile
.
Checksum
,
out
cachedTestResult
))
try
{
Logger
.
Log
(
$"
{
Path
.
GetFileName
(
assemblyPath
)}
- running"
);
testResult
=
await
_testExecutor
.
RunTestAsync
(
assemblyPath
,
cancellationToken
);
Logger
.
Log
(
$"
{
Path
.
GetFileName
(
assemblyPath
)}
- caching"
);
CacheTestResult
(
contentFile
,
testResult
);
var
cachedTestResult
=
await
_dataStorage
.
TryGetCachedTestResult
(
contentFile
.
Checksum
);
if
(
cachedTestResult
.
HasValue
)
{
Logger
.
Log
(
$"
{
Path
.
GetFileName
(
assemblyPath
)}
- cache hit"
);
return
Migrate
(
assemblyPath
,
cachedTestResult
.
Value
);
}
}
else
catch
(
Exception
ex
)
{
testResult
=
Migrate
(
assemblyPath
,
cachedTestResult
);
Logger
.
Log
(
$"
{
Path
.
GetFileName
(
assemblyPath
)}
- cache hit"
);
Logger
.
Log
(
$"Error reading cache
{
ex
}
"
);
}
Logger
.
Log
(
$"
{
Path
.
GetFileName
(
assemblyPath
)}
- running"
);
var
testResult
=
await
_testExecutor
.
RunTestAsync
(
assemblyPath
,
cancellationToken
);
await
CacheTestResult
(
contentFile
,
testResult
).
ConfigureAwait
(
true
);
return
testResult
;
}
...
...
@@ -77,7 +79,7 @@ private TestResult Migrate(string assemblyPath, CachedTestResult cachedTestResul
errorOutput
:
cachedTestResult
.
ErrorOutput
);
}
private
void
CacheTestResult
(
ContentFile
contentFile
,
TestResult
testResult
)
private
async
Task
CacheTestResult
(
ContentFile
contentFile
,
TestResult
testResult
)
{
try
{
...
...
@@ -87,8 +89,9 @@ private void CacheTestResult(ContentFile contentFile, TestResult testResult)
standardOutput
:
testResult
.
StandardOutput
,
errorOutput
:
testResult
.
ErrorOutput
,
resultsFileName
:
Path
.
GetFileName
(
testResult
.
ResultsFilePath
),
resultsFileContent
:
resultFileContent
);
_dataStorage
.
AddCachedTestResult
(
contentFile
,
cachedTestResult
);
resultsFileContent
:
resultFileContent
,
ellapsed
:
testResult
.
Elapsed
);
await
_dataStorage
.
AddCachedTestResult
(
contentFile
,
cachedTestResult
).
ConfigureAwait
(
true
);
}
catch
(
Exception
ex
)
{
...
...
src/Tools/Source/RunTests/Cache/IDataStorage.cs
浏览文件 @
433c827d
...
...
@@ -10,9 +10,9 @@ namespace RunTests.Cache
{
internal
interface
IDataStorage
{
bool
TryGetCachedTestResult
(
string
checksum
,
out
CachedTestResult
testResult
);
Task
<
CachedTestResult
?>
TryGetCachedTestResult
(
string
checksum
);
void
AddCachedTestResult
(
ContentFile
conentFile
,
CachedTestResult
testResult
);
Task
AddCachedTestResult
(
ContentFile
conentFile
,
CachedTestResult
testResult
);
}
internal
struct
CachedTestResult
...
...
@@ -22,19 +22,22 @@ internal struct CachedTestResult
internal
string
ErrorOutput
{
get
;
}
internal
string
ResultsFileName
{
get
;
}
internal
string
ResultsFileContent
{
get
;
}
internal
TimeSpan
Ellapsed
{
get
;
}
internal
CachedTestResult
(
int
exitCode
,
string
standardOutput
,
string
errorOutput
,
string
resultsFileName
,
string
resultsFileContent
)
string
resultsFileContent
,
TimeSpan
ellapsed
)
{
ExitCode
=
exitCode
;
StandardOutput
=
standardOutput
;
ErrorOutput
=
errorOutput
;
ResultsFileName
=
resultsFileName
;
ResultsFileContent
=
resultsFileContent
;
Ellapsed
=
ellapsed
;
}
}
}
...
...
src/Tools/Source/RunTests/Cache/LocalDataStorage.cs
浏览文件 @
433c827d
...
...
@@ -22,6 +22,7 @@ private enum StorageKind
ErrorOutput
,
ResultsFileContent
,
ResultsFileName
,
EllapsedSeconds
,
Content
}
...
...
@@ -35,8 +36,20 @@ internal LocalDataStorage(string storagePath = null)
_storagePath
=
storagePath
??
Path
.
Combine
(
Environment
.
GetFolderPath
(
Environment
.
SpecialFolder
.
LocalApplicationData
),
DirectoryName
);
}
public
bool
TryGetCachedTestResult
(
string
checksum
,
out
CachedTestResult
testResult
)
public
Task
<
CachedTestResult
?>
TryGetCachedTestResult
(
string
checksum
)
{
CachedTestResult
testResult
;
CachedTestResult
?
value
=
null
;
if
(
TryGetCachedTestResult
(
checksum
,
out
testResult
))
{
value
=
testResult
;
}
return
Task
.
FromResult
(
value
);
}
public
bool
TryGetCachedTestResult
(
string
checksum
,
out
CachedTestResult
testResult
)
{
testResult
=
default
(
CachedTestResult
);
var
storageFolder
=
GetStorageFolder
(
checksum
);
...
...
@@ -52,13 +65,15 @@ public bool TryGetCachedTestResult(string checksum, out CachedTestResult testRes
var
errorOutput
=
Read
(
checksum
,
StorageKind
.
ErrorOutput
);
var
resultsFileName
=
Read
(
checksum
,
StorageKind
.
ResultsFileName
);
var
resultsFileContent
=
Read
(
checksum
,
StorageKind
.
ResultsFileContent
);
var
ellapsed
=
Read
(
checksum
,
StorageKind
.
EllapsedSeconds
);
testResult
=
new
CachedTestResult
(
exitCode
:
int
.
Parse
(
exitCode
),
standardOutput
:
standardOutput
,
errorOutput
:
errorOutput
,
resultsFileName
:
resultsFileName
,
resultsFileContent
:
resultsFileContent
);
resultsFileContent
:
resultsFileContent
,
ellapsed
:
TimeSpan
.
FromSeconds
(
int
.
Parse
(
ellapsed
)));
return
true
;
}
catch
(
Exception
e
)
...
...
@@ -70,7 +85,7 @@ public bool TryGetCachedTestResult(string checksum, out CachedTestResult testRes
return
false
;
}
public
void
AddCachedTestResult
(
ContentFile
contentFile
,
CachedTestResult
testResult
)
public
Task
AddCachedTestResult
(
ContentFile
contentFile
,
CachedTestResult
testResult
)
{
var
checksum
=
contentFile
.
Checksum
;
var
storagePath
=
Path
.
Combine
(
_storagePath
,
checksum
);
...
...
@@ -78,7 +93,7 @@ public void AddCachedTestResult(ContentFile contentFile, CachedTestResult testRe
{
if
(!
FileUtil
.
EnsureDirectory
(
storagePath
))
{
return
;
return
Task
.
FromResult
(
true
)
;
}
Write
(
checksum
,
StorageKind
.
ExitCode
,
testResult
.
ExitCode
.
ToString
());
...
...
@@ -86,6 +101,7 @@ public void AddCachedTestResult(ContentFile contentFile, CachedTestResult testRe
Write
(
checksum
,
StorageKind
.
ErrorOutput
,
testResult
.
ErrorOutput
);
Write
(
checksum
,
StorageKind
.
ResultsFileName
,
testResult
.
ResultsFileName
);
Write
(
checksum
,
StorageKind
.
ResultsFileContent
,
testResult
.
ResultsFileContent
);
Write
(
checksum
,
StorageKind
.
EllapsedSeconds
,
testResult
.
Ellapsed
.
TotalSeconds
.
ToString
());
Write
(
checksum
,
StorageKind
.
Content
,
contentFile
.
Content
);
}
catch
(
Exception
e
)
...
...
@@ -94,6 +110,8 @@ public void AddCachedTestResult(ContentFile contentFile, CachedTestResult testRe
Logger
.
Log
(
$"Failed to log
{
checksum
}
{
e
.
Message
}
"
);
FileUtil
.
DeleteDirectory
(
storagePath
);
}
return
Task
.
FromResult
(
true
);
}
private
string
GetStorageFolder
(
string
checksum
)
...
...
src/Tools/Source/RunTests/Cache/WebDataStorage.cs
0 → 100644
浏览文件 @
433c827d
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using
Newtonsoft.Json.Linq
;
using
RestSharp
;
using
System
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Linq
;
using
System.Net
;
using
System.Text
;
using
System.Threading.Tasks
;
namespace
RunTests.Cache
{
internal
sealed
class
WebDataStorage
:
IDataStorage
{
private
const
string
NameExitCode
=
"ExitCode"
;
private
const
string
NameOutputStandard
=
"OutputStandard"
;
private
const
string
NameOutputError
=
"OutputError"
;
private
const
string
NameResultsFileName
=
"ResultsFileName"
;
private
const
string
NameResultsFileContent
=
"ResultsFileContent"
;
private
const
string
NameEllapsedSeconds
=
"EllapsedSeconds"
;
private
const
string
DashboardUriString
=
"http://jdash.azurewebsites.net"
;
private
readonly
RestClient
_restClient
=
new
RestClient
(
DashboardUriString
);
public
async
Task
AddCachedTestResult
(
ContentFile
contentFile
,
CachedTestResult
testResult
)
{
var
obj
=
new
JObject
();
obj
[
"TestResultData"
]
=
CreateTestResultData
(
testResult
);
obj
[
"TestSourceData"
]
=
CreateTestSourceData
();
var
request
=
new
RestRequest
(
$"api/testcache/
{
contentFile
.
Checksum
}
"
);
request
.
Method
=
Method
.
PUT
;
request
.
RequestFormat
=
DataFormat
.
Json
;
request
.
AddParameter
(
"text/json"
,
obj
.
ToString
(),
ParameterType
.
RequestBody
);
var
response
=
await
_restClient
.
ExecuteTaskAsync
(
request
);
}
public
async
Task
<
CachedTestResult
?>
TryGetCachedTestResult
(
string
checksum
)
{
try
{
var
request
=
new
RestRequest
(
$"api/testcache/
{
checksum
}
"
);
var
response
=
await
_restClient
.
ExecuteGetTaskAsync
(
request
);
if
(
response
.
StatusCode
!=
HttpStatusCode
.
OK
)
{
return
null
;
}
var
obj
=
JObject
.
Parse
(
response
.
Content
);
var
result
=
new
CachedTestResult
(
exitCode
:
obj
.
Value
<
int
>(
NameExitCode
),
standardOutput
:
obj
.
Value
<
string
>(
NameOutputStandard
),
errorOutput
:
obj
.
Value
<
string
>(
NameOutputError
),
resultsFileName
:
obj
.
Value
<
string
>(
NameResultsFileName
),
resultsFileContent
:
obj
.
Value
<
string
>(
NameResultsFileContent
),
ellapsed
:
TimeSpan
.
FromSeconds
(
0
));
return
result
;
}
catch
{
return
null
;
}
}
private
static
JObject
CreateTestResultData
(
CachedTestResult
testResult
)
{
var
obj
=
new
JObject
();
obj
[
NameExitCode
]
=
testResult
.
ExitCode
;
obj
[
NameOutputStandard
]
=
testResult
.
StandardOutput
;
obj
[
NameOutputStandard
]
=
testResult
.
ErrorOutput
;
obj
[
NameResultsFileName
]
=
testResult
.
ResultsFileName
;
obj
[
NameResultsFileContent
]
=
testResult
.
ResultsFileContent
;
obj
[
NameEllapsedSeconds
]
=
testResult
.
Ellapsed
.
TotalSeconds
;
return
obj
;
}
private
static
JObject
CreateTestSourceData
()
{
var
obj
=
new
JObject
();
obj
[
"MachineName"
]
=
Environment
.
MachineName
;
obj
[
"TestRoot"
]
=
""
;
return
obj
;
}
}
}
src/Tools/Source/RunTests/Program.cs
浏览文件 @
433c827d
...
...
@@ -33,7 +33,18 @@ internal static int Main(string[] args)
ITestExecutor
testExecutor
=
new
ProcessTestExecutor
(
options
);
if
(
options
.
UseCachedResults
)
{
testExecutor
=
new
CachingTestExecutor
(
options
,
testExecutor
,
new
LocalDataStorage
());
// The web caching layer is still being worked on. For now want to limit it to Roslyn developers
// and Jenkins runs by default until we work on this a bit more. Anyone reading this who wants
// to try it out should feel free to opt into this.
IDataStorage
dataStorage
=
new
LocalDataStorage
();
if
(
StringComparer
.
OrdinalIgnoreCase
.
Equals
(
"REDMOND"
,
Environment
.
UserDomainName
)
||
!
string
.
IsNullOrEmpty
(
Environment
.
GetEnvironmentVariable
(
"JENKINS_URL"
)))
{
Console
.
WriteLine
(
"Using web cache"
);
dataStorage
=
new
WebDataStorage
();
}
testExecutor
=
new
CachingTestExecutor
(
options
,
testExecutor
,
dataStorage
);
}
var
testRunner
=
new
TestRunner
(
options
,
testExecutor
);
...
...
src/Tools/Source/RunTests/RunTests.csproj
浏览文件 @
433c827d
...
...
@@ -13,9 +13,13 @@
<AssemblyName>
RunTests
</AssemblyName>
<SolutionDir
Condition=
"$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'"
>
..\..\
</SolutionDir>
<TargetFrameworkVersion>
v4.5
</TargetFrameworkVersion>
<SignAssembly>
false
</SignAssembly>
<OutDir>
$(OutDir)RunTests\
</OutDir>
</PropertyGroup>
<PropertyGroup
Condition=
" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "
/>
<PropertyGroup
Condition=
" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "
/>
<PropertyGroup>
</PropertyGroup>
<ItemGroup>
<Reference
Include=
"System"
/>
<Reference
Include=
"System.Core"
/>
...
...
@@ -26,6 +30,7 @@
<Compile
Include=
"Cache\ContentUtil.cs"
/>
<Compile
Include=
"Cache\CachingTestExecutor.cs"
/>
<Compile
Include=
"Cache\ConentFile.cs"
/>
<Compile
Include=
"Cache\WebDataStorage.cs"
/>
<Compile
Include=
"Constants.cs"
/>
<Compile
Include=
"FileUtil.cs"
/>
<Compile
Include=
"Cache\IDataStorage.cs"
/>
...
...
@@ -39,7 +44,10 @@
<Compile
Include=
"TestRunner.cs"
/>
<Compile
Include=
"ConsoleUtil.cs"
/>
</ItemGroup>
<ItemGroup>
<None
Include=
"project.json"
/>
</ItemGroup>
<ImportGroup
Label=
"Targets"
>
<Import
Project=
"..\..\..\..\build\Targets\VSL.Imports.targets"
/>
</ImportGroup>
</Project>
\ No newline at end of file
</Project>
src/Tools/Source/RunTests/project.json
0 → 100644
浏览文件 @
433c827d
{
"dependencies"
:
{
"Newtonsoft.Json"
:
"8.0.2"
,
"RestSharp"
:
"105.2.3"
,
},
"frameworks"
:
{
"net45"
:
{
}
},
"runtimes"
:
{
"win7"
:
{
},
"win7-anycpu"
:
{
}
}
}
src/Tools/Source/RunTests/project.lock.json
0 → 100644
浏览文件 @
433c827d
{
"locked"
:
false
,
"version"
:
1
,
"targets"
:
{
".NETFramework,Version=v4.5"
:
{
"Newtonsoft.Json/8.0.2"
:
{
"compile"
:
{
"lib/net45/Newtonsoft.Json.dll"
:
{}
},
"runtime"
:
{
"lib/net45/Newtonsoft.Json.dll"
:
{}
}
},
"RestSharp/105.2.3"
:
{
"compile"
:
{
"lib/net45/RestSharp.dll"
:
{}
},
"runtime"
:
{
"lib/net45/RestSharp.dll"
:
{}
}
}
},
".NETFramework,Version=v4.5/win7"
:
{
"Newtonsoft.Json/8.0.2"
:
{
"compile"
:
{
"lib/net45/Newtonsoft.Json.dll"
:
{}
},
"runtime"
:
{
"lib/net45/Newtonsoft.Json.dll"
:
{}
}
},
"RestSharp/105.2.3"
:
{
"compile"
:
{
"lib/net45/RestSharp.dll"
:
{}
},
"runtime"
:
{
"lib/net45/RestSharp.dll"
:
{}
}
}
},
".NETFramework,Version=v4.5/win7-anycpu"
:
{
"Newtonsoft.Json/8.0.2"
:
{
"compile"
:
{
"lib/net45/Newtonsoft.Json.dll"
:
{}
},
"runtime"
:
{
"lib/net45/Newtonsoft.Json.dll"
:
{}
}
},
"RestSharp/105.2.3"
:
{
"compile"
:
{
"lib/net45/RestSharp.dll"
:
{}
},
"runtime"
:
{
"lib/net45/RestSharp.dll"
:
{}
}
}
}
},
"libraries"
:
{
"Newtonsoft.Json/8.0.2"
:
{
"sha512"
:
"e5yWmEfu68rmtG431zl9N/7PlNKQDIuiDW5MHlEFAZcecakcxrIGnKqrPAtWNILzK2oNanRB5cD150MYhECK3g=="
,
"type"
:
"Package"
,
"files"
:
[
"[Content_Types].xml"
,
"_rels/.rels"
,
"lib/net20/Newtonsoft.Json.dll"
,
"lib/net20/Newtonsoft.Json.xml"
,
"lib/net35/Newtonsoft.Json.dll"
,
"lib/net35/Newtonsoft.Json.xml"
,
"lib/net40/Newtonsoft.Json.dll"
,
"lib/net40/Newtonsoft.Json.xml"
,
"lib/net45/Newtonsoft.Json.dll"
,
"lib/net45/Newtonsoft.Json.xml"
,
"lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.dll"
,
"lib/portable-net40+sl5+wp80+win8+wpa81/Newtonsoft.Json.xml"
,
"lib/portable-net45+wp80+win8+wpa81+dnxcore50/Newtonsoft.Json.dll"
,
"lib/portable-net45+wp80+win8+wpa81+dnxcore50/Newtonsoft.Json.xml"
,
"Newtonsoft.Json.nuspec"
,
"package/services/metadata/core-properties/cc8c591d554640789c6a6ef6456f7772.psmdcp"
,
"tools/install.ps1"
]
},
"RestSharp/105.2.3"
:
{
"sha512"
:
"50LkciOclb7Lza9QXqR9reKeUoPlDQiFD4iBdOmd6twOBmTtqEFIOXQgdDdsTHQg4HcGh6EvrM6gN1X72vkJLA=="
,
"type"
:
"Package"
,
"files"
:
[
"[Content_Types].xml"
,
"_rels/.rels"
,
"lib/MonoAndroid10/RestSharp.dll"
,
"lib/MonoAndroid10/RestSharp.xml"
,
"lib/MonoTouch10/RestSharp.dll"
,
"lib/MonoTouch10/RestSharp.xml"
,
"lib/net35/RestSharp.dll"
,
"lib/net35/RestSharp.xml"
,
"lib/net4/RestSharp.dll"
,
"lib/net4/RestSharp.xml"
,
"lib/net45/RestSharp.dll"
,
"lib/net45/RestSharp.xml"
,
"lib/net451/RestSharp.dll"
,
"lib/net451/RestSharp.xml"
,
"lib/net452/RestSharp.dll"
,
"lib/net452/RestSharp.xml"
,
"lib/net46/RestSharp.dll"
,
"lib/net46/RestSharp.xml"
,
"lib/net4-client/RestSharp.dll"
,
"lib/net4-client/RestSharp.xml"
,
"lib/sl5/RestSharp.dll"
,
"lib/sl5/RestSharp.xml"
,
"lib/windowsphone8/RestSharp.dll"
,
"lib/windowsphone8/RestSharp.xml"
,
"lib/windowsphone81/RestSharp.dll"
,
"lib/windowsphone81/RestSharp.xml"
,
"lib/Xamarin.iOS10/RestSharp.dll"
,
"lib/Xamarin.iOS10/RestSharp.xml"
,
"package/services/metadata/core-properties/fe62c7f38ace4dbeaf729ff7b329d22a.psmdcp"
,
"readme.txt"
,
"RestSharp.nuspec"
]
}
},
"projectFileDependencyGroups"
:
{
""
:
[
"Newtonsoft.Json >= 8.0.2"
,
"RestSharp >= 105.2.3"
],
".NETFramework,Version=v4.5"
:
[]
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录