Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
97f5c112
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
97f5c112
编写于
9月 23, 2016
作者:
D
Dirk Baeumer
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into dbaeumer/TS2.0
上级
a464b8a7
fd97fc42
变更
7
显示空白变更内容
内联
并排
Showing
7 changed file
with
258 addition
and
54 deletion
+258
-54
build/gulpfile.vscode.js
build/gulpfile.vscode.js
+2
-1
build/gulpfile.vscode.linux.js
build/gulpfile.vscode.linux.js
+4
-4
resources/win32/bin/cat.exe
resources/win32/bin/cat.exe
+0
-0
src/vs/code/electron-main/main.ts
src/vs/code/electron-main/main.ts
+49
-17
src/vs/platform/extensionManagement/common/extensionManagement.ts
...latform/extensionManagement/common/extensionManagement.ts
+7
-0
src/vs/platform/extensionManagement/node/extensionGalleryService.ts
...tform/extensionManagement/node/extensionGalleryService.ts
+114
-20
src/vs/platform/extensionManagement/node/extensionManagementService.ts
...rm/extensionManagement/node/extensionManagementService.ts
+82
-12
未找到文件。
build/gulpfile.vscode.js
浏览文件 @
97f5c112
...
...
@@ -38,7 +38,8 @@ const nodeModules = ['electron', 'original-fs']
// Build
const
builtInExtensions
=
[
{
name
:
'
ms-vscode.node-debug
'
,
version
:
'
1.6.2
'
}
{
name
:
'
ms-vscode.node-debug
'
,
version
:
'
1.6.5
'
},
{
name
:
'
ms-vscode.node-debug2
'
,
version
:
'
0.0.1
'
}
];
const
vscodeEntryPoints
=
_
.
flatten
([
...
...
build/gulpfile.vscode.linux.js
浏览文件 @
97f5c112
...
...
@@ -151,14 +151,14 @@ gulp.task('clean-vscode-linux-arm-rpm', util.rimraf('.build/linux/rpm/armhf'));
gulp
.
task
(
'
vscode-linux-ia32-prepare-deb
'
,
[
'
clean-vscode-linux-ia32-deb
'
,
'
vscode-linux-ia32-min
'
],
prepareDebPackage
(
'
ia32
'
));
gulp
.
task
(
'
vscode-linux-x64-prepare-deb
'
,
[
'
clean-vscode-linux-x64-deb
'
,
'
vscode-linux-x64-min
'
],
prepareDebPackage
(
'
x64
'
));
gulp
.
task
(
'
vscode-linux-arm-prepare-deb
'
,
[
'
clean-vscode-linux-arm-deb
'
,
'
vscode-linux-arm-min
'
],
prepareDebPackage
(
'
arm
hf
'
));
gulp
.
task
(
'
vscode-linux-arm-prepare-deb
'
,
[
'
clean-vscode-linux-arm-deb
'
,
'
vscode-linux-arm-min
'
],
prepareDebPackage
(
'
arm
'
));
gulp
.
task
(
'
vscode-linux-ia32-build-deb
'
,
[
'
vscode-linux-ia32-prepare-deb
'
],
buildDebPackage
(
'
ia32
'
));
gulp
.
task
(
'
vscode-linux-x64-build-deb
'
,
[
'
vscode-linux-x64-prepare-deb
'
],
buildDebPackage
(
'
x64
'
));
gulp
.
task
(
'
vscode-linux-arm-build-deb
'
,
[
'
vscode-linux-arm-prepare-deb
'
],
buildDebPackage
(
'
arm
hf
'
));
gulp
.
task
(
'
vscode-linux-arm-build-deb
'
,
[
'
vscode-linux-arm-prepare-deb
'
],
buildDebPackage
(
'
arm
'
));
gulp
.
task
(
'
vscode-linux-ia32-prepare-rpm
'
,
[
'
clean-vscode-linux-ia32-rpm
'
,
'
vscode-linux-ia32-min
'
],
prepareRpmPackage
(
'
ia32
'
));
gulp
.
task
(
'
vscode-linux-x64-prepare-rpm
'
,
[
'
clean-vscode-linux-x64-rpm
'
,
'
vscode-linux-x64-min
'
],
prepareRpmPackage
(
'
x64
'
));
gulp
.
task
(
'
vscode-linux-arm-prepare-rpm
'
,
[
'
clean-vscode-linux-arm-rpm
'
,
'
vscode-linux-arm-min
'
],
prepareRpmPackage
(
'
arm
hf
'
));
gulp
.
task
(
'
vscode-linux-arm-prepare-rpm
'
,
[
'
clean-vscode-linux-arm-rpm
'
,
'
vscode-linux-arm-min
'
],
prepareRpmPackage
(
'
arm
'
));
gulp
.
task
(
'
vscode-linux-ia32-build-rpm
'
,
[
'
vscode-linux-ia32-prepare-rpm
'
],
buildRpmPackage
(
'
ia32
'
));
gulp
.
task
(
'
vscode-linux-x64-build-rpm
'
,
[
'
vscode-linux-x64-prepare-rpm
'
],
buildRpmPackage
(
'
x64
'
));
gulp
.
task
(
'
vscode-linux-arm-build-rpm
'
,
[
'
vscode-linux-arm-prepare-rpm
'
],
buildRpmPackage
(
'
arm
hf
'
));
gulp
.
task
(
'
vscode-linux-arm-build-rpm
'
,
[
'
vscode-linux-arm-prepare-rpm
'
],
buildRpmPackage
(
'
arm
'
));
resources/win32/bin/cat.exe
浏览文件 @
97f5c112
无法预览此类型文件
src/vs/code/electron-main/main.ts
浏览文件 @
97f5c112
...
...
@@ -6,7 +6,6 @@
'
use strict
'
;
import
*
as
nls
from
'
vs/nls
'
;
import
*
as
fs
from
'
original-fs
'
;
import
{
app
,
ipcMain
as
ipc
}
from
'
electron
'
;
import
{
assign
}
from
'
vs/base/common/objects
'
;
import
*
as
platform
from
'
vs/base/common/platform
'
;
...
...
@@ -39,11 +38,15 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import
{
ConfigurationService
}
from
'
vs/platform/configuration/node/configurationService
'
;
import
{
IRequestService
}
from
'
vs/platform/request/common/request
'
;
import
{
RequestService
}
from
'
vs/platform/request/node/requestService
'
;
import
*
as
cp
from
'
child_process
'
;
import
{
generateUuid
}
from
'
vs/base/common/uuid
'
;
import
{
getPathLabel
}
from
'
vs/base/common/labels
'
;
import
{
URLChannel
}
from
'
vs/platform/url/common/urlIpc
'
;
import
{
URLService
}
from
'
vs/platform/url/electron-main/urlService
'
;
import
*
as
fs
from
'
original-fs
'
;
import
*
as
cp
from
'
child_process
'
;
import
*
as
path
from
'
path
'
;
function
quit
(
accessor
:
ServicesAccessor
,
error
?:
Error
);
function
quit
(
accessor
:
ServicesAccessor
,
message
?:
string
);
function
quit
(
accessor
:
ServicesAccessor
,
arg
?:
any
)
{
...
...
@@ -193,8 +196,10 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: IProce
// Install JumpList on Windows
if
(
platform
.
isWindows
)
{
app
.
setJumpList
([
{
const
jumpList
:
Electron
.
JumpListCategory
[]
=
[];
// Tasks
jumpList
.
push
({
type
:
'
tasks
'
,
items
:
[
{
...
...
@@ -207,11 +212,38 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: IProce
iconIndex
:
0
}
]
},
{
});
// Recent Folders
const
folders
=
windowsService
.
getRecentPathsList
().
folders
;
if
(
folders
.
length
>
0
)
{
jumpList
.
push
({
type
:
'
custom
'
,
name
:
'
Recent Folders
'
,
items
:
windowsService
.
getRecentPathsList
().
folders
.
slice
(
0
,
7
/* limit number of entries here */
).
map
(
folder
=>
{
return
<
Electron
.
JumpListItem
>
{
type
:
'
task
'
,
title
:
getPathLabel
(
folder
),
description
:
nls
.
localize
(
'
folderDesc
'
,
"
{0} {1}
"
,
path
.
basename
(
folder
),
getPathLabel
(
path
.
dirname
(
folder
))),
program
:
process
.
execPath
,
args
:
folder
,
// open folder,
iconPath
:
process
.
execPath
,
iconIndex
:
0
};
})
});
}
// Recent
jumpList
.
push
({
type
:
'
recent
'
// this enables to show files in the "recent" category
});
try
{
app
.
setJumpList
(
jumpList
);
}
catch
(
error
)
{
logService
.
log
(
'
#setJumpList
'
,
error
);
// since setJumpList is relatively new API, make sure to guard for errors
}
]);
}
// Setup auto update
...
...
src/vs/platform/extensionManagement/common/extensionManagement.ts
浏览文件 @
97f5c112
...
...
@@ -103,6 +103,10 @@ export interface IExtensionIdentity {
publisher
:
string
;
}
export
interface
IGalleryExtensionProperties
{
dependencies
?:
string
[];
}
export
interface
IGalleryExtensionAssets
{
manifest
:
string
;
readme
:
string
;
...
...
@@ -126,6 +130,7 @@ export interface IGalleryExtension {
rating
:
number
;
ratingCount
:
number
;
assets
:
IGalleryExtensionAssets
;
properties
:
IGalleryExtensionProperties
;
downloadHeaders
:
{
[
key
:
string
]:
string
;
};
}
...
...
@@ -184,6 +189,8 @@ export interface IExtensionGalleryService {
query
(
options
?:
IQueryOptions
):
TPromise
<
IPager
<
IGalleryExtension
>>
;
download
(
extension
:
IGalleryExtension
):
TPromise
<
string
>
;
getAsset
(
url
:
string
):
TPromise
<
IRequestContext
>
;
loadCompatibleVersion
(
extension
:
IGalleryExtension
):
TPromise
<
IGalleryExtension
>
;
getAllDependencies
(
extension
:
IGalleryExtension
):
TPromise
<
IGalleryExtension
[]
>
;
}
export
interface
InstallExtensionEvent
{
...
...
src/vs/platform/extensionManagement/node/extensionGalleryService.ts
浏览文件 @
97f5c112
...
...
@@ -7,6 +7,8 @@ import { localize } from 'vs/nls';
import
{
tmpdir
}
from
'
os
'
;
import
*
as
path
from
'
path
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
distinct
}
from
'
vs/base/common/arrays
'
;
import
{
ArraySet
}
from
'
vs/base/common/set
'
;
import
{
IGalleryExtension
,
IExtensionGalleryService
,
IQueryOptions
,
SortBy
,
SortOrder
,
IExtensionManifest
}
from
'
vs/platform/extensionManagement/common/extensionManagement
'
;
import
{
getGalleryExtensionTelemetryData
}
from
'
vs/platform/extensionManagement/common/extensionTelemetry
'
;
import
{
isUndefined
}
from
'
vs/base/common/types
'
;
...
...
@@ -26,11 +28,17 @@ interface IRawGalleryExtensionFile {
source
:
string
;
}
interface
IRawGalleryExtensionProperty
{
key
:
string
;
value
:
string
;
}
interface
IRawGalleryExtensionVersion
{
version
:
string
;
lastUpdated
:
string
;
assetUri
:
string
;
files
:
IRawGalleryExtensionFile
[];
properties
:
IRawGalleryExtensionProperty
[];
}
interface
IRawGalleryExtensionStatistics
{
...
...
@@ -90,7 +98,11 @@ const AssetType = {
Details
:
'
Microsoft.VisualStudio.Services.Content.Details
'
,
Manifest
:
'
Microsoft.VisualStudio.Code.Manifest
'
,
VSIX
:
'
Microsoft.VisualStudio.Services.VSIXPackage
'
,
License
:
'
Microsoft.VisualStudio.Services.Content.License
'
License
:
'
Microsoft.VisualStudio.Services.Content.License
'
,
};
const
PropertyType
=
{
Dependency
:
'
Microsoft.VisualStudio.Code.ExtensionDependencies
'
};
interface
ICriterium
{
...
...
@@ -178,7 +190,13 @@ function getAssetSource(files: IRawGalleryExtensionFile[], type: string): string
const
result
=
files
.
filter
(
f
=>
f
.
assetType
===
type
)[
0
];
return
result
&&
result
.
source
;
}
function
getDependencies
(
properties
:
IRawGalleryExtensionProperty
[]):
string
[]
{
const
values
=
properties
.
filter
(
p
=>
p
.
key
===
PropertyType
.
Dependency
);
if
(
values
.
length
&&
values
[
0
].
value
)
{
return
values
[
0
].
value
.
split
(
'
,
'
);
}
return
[];
}
function
toExtension
(
galleryExtension
:
IRawGalleryExtension
,
extensionsGalleryUrl
:
string
,
downloadHeaders
:
{
[
key
:
string
]:
string
;
}):
IGalleryExtension
{
const
[
version
]
=
galleryExtension
.
versions
;
...
...
@@ -203,6 +221,8 @@ function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUr
license
:
getAssetSource
(
version
.
files
,
AssetType
.
License
)
};
const
dependencies
=
version
.
properties
?
getDependencies
(
version
.
properties
)
:
void
0
;
return
{
id
:
galleryExtension
.
extensionId
,
name
:
galleryExtension
.
extensionName
,
...
...
@@ -217,6 +237,9 @@ function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUr
rating
:
getStatistic
(
galleryExtension
.
statistics
,
'
averagerating
'
),
ratingCount
:
getStatistic
(
galleryExtension
.
statistics
,
'
ratingcount
'
),
assets
,
properties
:
{
dependencies
},
downloadHeaders
};
}
...
...
@@ -337,22 +360,8 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
}
download
(
extension
:
IGalleryExtension
):
TPromise
<
string
>
{
const
query
=
new
Query
()
.
withFlags
(
Flags
.
IncludeVersions
,
Flags
.
IncludeFiles
)
.
withPage
(
1
,
1
)
.
withFilter
(
FilterType
.
Target
,
'
Microsoft.VisualStudio.Code
'
)
.
withAssetTypes
(
AssetType
.
Manifest
,
AssetType
.
VSIX
)
.
withFilter
(
FilterType
.
ExtensionId
,
extension
.
id
);
return
this
.
queryGallery
(
query
).
then
(({
galleryExtensions
})
=>
{
const
[
rawExtension
]
=
galleryExtensions
;
if
(
!
rawExtension
)
{
return
TPromise
.
wrapError
(
new
Error
(
localize
(
'
notFound
'
,
"
Extension not found
"
)));
}
return
this
.
getLastValidExtensionVersion
(
rawExtension
,
rawExtension
.
versions
).
then
(
rawVersion
=>
{
const
url
=
`
${
getAssetSource
(
rawVersion
.
files
,
AssetType
.
VSIX
)
}
?install=true`
;
return
this
.
loadCompatibleVersion
(
extension
).
then
(
extension
=>
{
const
url
=
extension
.
assets
.
download
;
const
zipPath
=
path
.
join
(
tmpdir
(),
extension
.
id
);
const
data
=
getGalleryExtensionTelemetryData
(
extension
);
const
startTime
=
new
Date
().
getTime
();
...
...
@@ -364,13 +373,89 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
.
then
(()
=>
log
(
new
Date
().
getTime
()
-
startTime
))
.
then
(()
=>
zipPath
);
});
});
}
getAsset
(
url
:
string
):
TPromise
<
IRequestContext
>
{
return
this
.
_getAsset
({
url
});
}
getAllDependencies
(
extension
:
IGalleryExtension
):
TPromise
<
IGalleryExtension
[]
>
{
return
this
.
loadCompatibleVersion
(
<
IGalleryExtension
>
extension
)
.
then
(
compatible
=>
this
.
getDependenciesReccursively
(
compatible
.
properties
.
dependencies
,
[
extension
]))
.
then
(
dependencies
=>
dependencies
.
slice
(
1
));
}
loadCompatibleVersion
(
extension
:
IGalleryExtension
):
TPromise
<
IGalleryExtension
>
{
// TODO:sandy: Check if the given version is compatible
const
query
=
new
Query
()
.
withFlags
(
Flags
.
IncludeVersions
,
Flags
.
IncludeFiles
,
Flags
.
IncludeVersionProperties
)
.
withPage
(
1
,
1
)
.
withFilter
(
FilterType
.
Target
,
'
Microsoft.VisualStudio.Code
'
)
.
withAssetTypes
(
AssetType
.
Manifest
,
AssetType
.
VSIX
)
.
withFilter
(
FilterType
.
ExtensionId
,
extension
.
id
);
return
this
.
queryGallery
(
query
).
then
(({
galleryExtensions
})
=>
{
const
[
rawExtension
]
=
galleryExtensions
;
if
(
!
rawExtension
)
{
return
TPromise
.
wrapError
(
new
Error
(
localize
(
'
notFound
'
,
"
Extension not found
"
)));
}
return
this
.
getLastValidExtensionVersion
(
rawExtension
,
rawExtension
.
versions
)
.
then
(
rawVersion
=>
{
extension
.
properties
.
dependencies
=
getDependencies
(
rawVersion
.
properties
);
extension
.
assets
.
download
=
`
${
getAssetSource
(
rawVersion
.
files
,
AssetType
.
VSIX
)
}
?install=true`
;
return
extension
;
});
});
}
private
loadDependencies
(
extensionNames
:
string
[]):
TPromise
<
IGalleryExtension
[]
>
{
let
query
=
new
Query
()
.
withFlags
(
Flags
.
IncludeVersions
,
Flags
.
IncludeAssetUri
,
Flags
.
IncludeStatistics
,
Flags
.
IncludeFiles
,
Flags
.
IncludeVersionProperties
)
.
withPage
(
1
,
extensionNames
.
length
)
.
withFilter
(
FilterType
.
Target
,
'
Microsoft.VisualStudio.Code
'
)
.
withAssetTypes
(
AssetType
.
Icon
,
AssetType
.
License
,
AssetType
.
Details
,
AssetType
.
Manifest
,
AssetType
.
VSIX
);
query
=
extensionNames
.
reduce
((
query
,
name
)
=>
query
.
withFilter
(
FilterType
.
ExtensionName
,
name
),
query
);
return
this
.
queryGallery
(
query
)
.
then
(
result
=>
this
.
getCommonHeaders
()
.
then
(
downloadHeaders
=>
{
const
dependencies
=
[];
const
ids
=
[];
for
(
const
galleryExtension
of
result
.
galleryExtensions
)
{
if
(
ids
.
indexOf
(
galleryExtension
.
extensionId
)
===
-
1
)
{
dependencies
.
push
(
toExtension
(
galleryExtension
,
this
.
extensionsGalleryUrl
,
downloadHeaders
));
ids
.
push
(
galleryExtension
.
extensionId
);
}
}
return
dependencies
;
})
);
}
private
getDependenciesReccursively
(
toGet
:
string
[],
result
:
IGalleryExtension
[]):
TPromise
<
IGalleryExtension
[]
>
{
if
(
!
toGet
||
!
toGet
.
length
)
{
return
TPromise
.
wrap
(
result
);
}
toGet
=
result
.
length
?
toGet
.
filter
(
e
=>
!
ExtensionGalleryService
.
hasExtensionByName
(
result
,
e
))
:
toGet
;
if
(
!
toGet
.
length
)
{
return
TPromise
.
wrap
(
result
);
}
return
this
.
loadDependencies
(
toGet
)
.
then
(
loadedDependencies
=>
{
const
dependenciesSet
=
new
ArraySet
<
string
>
();
for
(
const
dep
of
loadedDependencies
)
{
if
(
dep
.
properties
.
dependencies
)
{
dep
.
properties
.
dependencies
.
forEach
(
d
=>
dependenciesSet
.
set
(
d
));
}
}
result
=
distinct
(
result
.
concat
(
loadedDependencies
),
d
=>
d
.
id
);
const
dependencies
=
dependenciesSet
.
elements
.
filter
(
d
=>
!
ExtensionGalleryService
.
hasExtensionByName
(
result
,
d
));
return
this
.
getDependenciesReccursively
(
dependencies
,
result
);
});
}
/**
* Always try with the `redirect=true` query string.
* If that does not return 200, try without it.
...
...
@@ -416,4 +501,13 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
return
version
;
});
}
private
static
hasExtensionByName
(
extensions
:
IGalleryExtension
[],
name
:
string
):
boolean
{
for
(
const
extension
of
extensions
)
{
if
(
`
${
extension
.
publisher
}
.
${
extension
.
name
}
`
===
name
)
{
return
true
;
}
}
return
false
;
}
}
\ No newline at end of file
src/vs/platform/extensionManagement/node/extensionManagementService.ts
浏览文件 @
97f5c112
...
...
@@ -8,6 +8,7 @@
import
nls
=
require
(
'
vs/nls
'
);
import
*
as
path
from
'
path
'
;
import
*
as
pfs
from
'
vs/base/node/pfs
'
;
import
*
as
errors
from
'
vs/base/common/errors
'
;
import
{
assign
}
from
'
vs/base/common/objects
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
flatten
}
from
'
vs/base/common/arrays
'
;
...
...
@@ -24,6 +25,7 @@ import Event, { Emitter } from 'vs/base/common/event';
import
*
as
semver
from
'
semver
'
;
import
{
groupBy
,
values
}
from
'
vs/base/common/collections
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
IChoiceService
,
Severity
}
from
'
vs/platform/message/common/message
'
;
const
SystemExtensionsRoot
=
path
.
normalize
(
path
.
join
(
URI
.
parse
(
require
.
toUrl
(
''
)).
fsPath
,
'
..
'
,
'
extensions
'
));
...
...
@@ -106,6 +108,7 @@ export class ExtensionManagementService implements IExtensionManagementService {
constructor
(
@
IEnvironmentService
private
environmentService
:
IEnvironmentService
,
@
IChoiceService
private
choiceService
:
IChoiceService
,
@
IExtensionGalleryService
private
galleryService
:
IExtensionGalleryService
)
{
this
.
extensionsPath
=
environmentService
.
extensionsPath
;
...
...
@@ -135,30 +138,97 @@ export class ExtensionManagementService implements IExtensionManagementService {
});
}
installFromGallery
(
extension
:
IGalleryExtension
):
TPromise
<
void
>
{
installFromGallery
(
extension
:
IGalleryExtension
,
checkDependecies
:
boolean
=
true
):
TPromise
<
void
>
{
const
id
=
getExtensionId
(
extension
,
extension
.
version
);
return
this
.
isObsolete
(
id
).
then
(
isObsolete
=>
{
if
(
isObsolete
)
{
return
TPromise
.
wrapError
<
void
>
(
new
Error
(
nls
.
localize
(
'
restartCode
'
,
"
Please restart Code before reinstalling {0}.
"
,
extension
.
displayName
||
extension
.
name
)));
}
this
.
_onInstallExtension
.
fire
({
id
,
gallery
:
extension
});
return
this
.
galleryService
.
loadCompatibleVersion
(
extension
)
.
then
(
compatibleVersion
=>
this
.
installCompatibleVersion
(
compatibleVersion
,
checkDependecies
))
.
then
(
local
=>
this
.
_onDidInstallExtension
.
fire
({
id
,
local
,
gallery
:
extension
}),
error
=>
{
this
.
_onDidInstallExtension
.
fire
({
id
,
gallery
:
extension
,
error
});
return
TPromise
.
wrapError
(
error
);
}
);
});
}
private
installCompatibleVersion
(
extension
:
IGalleryExtension
,
checkDependecies
:
boolean
):
TPromise
<
ILocalExtension
>
{
const
dependencies
=
checkDependecies
?
this
.
getDependenciesToInstall
(
extension
)
:
[];
if
(
!
dependencies
.
length
)
{
return
this
.
downloadAndInstall
(
extension
);
}
const
message
=
nls
.
localize
(
'
installDependecies
'
,
"
This extension has dependencies. Would you like to install them along with it?
"
);
const
options
=
[
nls
.
localize
(
'
installWithDependenices
'
,
"
Install With Dependencies
"
),
nls
.
localize
(
'
installWithoutDependenices
'
,
"
Install only this
"
),
nls
.
localize
(
'
close
'
,
"
Close
"
)
];
return
this
.
choiceService
.
choose
(
Severity
.
Info
,
message
,
options
)
.
then
(
value
=>
{
switch
(
value
)
{
case
0
:
return
this
.
installWithDependencies
(
extension
);
case
1
:
return
this
.
downloadAndInstall
(
extension
);
default
:
return
TPromise
.
wrapError
(
errors
.
canceled
());
}
});
}
private
getDependenciesToInstall
(
extension
:
IGalleryExtension
):
string
[]
{
const
extensionName
=
`
${
extension
.
publisher
}
.
${
extension
.
name
}
`
;
return
extension
.
properties
.
dependencies
?
extension
.
properties
.
dependencies
.
filter
(
name
=>
name
!==
extensionName
)
:
[];
}
private
installWithDependencies
(
extension
:
IGalleryExtension
):
TPromise
<
ILocalExtension
>
{
return
this
.
galleryService
.
getAllDependencies
(
extension
)
.
then
(
allDependencies
=>
this
.
filterOutInstalled
(
allDependencies
))
.
then
(
toInstall
=>
this
.
bulkInstallWithDependencies
(
extension
,
toInstall
));
}
private
bulkInstallWithDependencies
(
extension
:
IGalleryExtension
,
dependecies
:
IGalleryExtension
[]):
TPromise
<
ILocalExtension
>
{
return
this
.
downloadAndInstall
(
extension
)
.
then
(
localExtension
=>
TPromise
.
join
(
dependecies
.
map
((
dep
)
=>
this
.
installFromGallery
(
dep
,
false
)))
.
then
(()
=>
localExtension
,
error
=>
this
.
rollback
(
localExtension
,
dependecies
).
then
(()
=>
error
)));
}
private
rollback
(
localExtension
:
ILocalExtension
,
dependecies
:
IGalleryExtension
[]):
TPromise
<
void
>
{
return
this
.
uninstall
(
localExtension
)
.
then
(()
=>
this
.
filterOutUnInstalled
(
dependecies
))
.
then
(
installed
=>
TPromise
.
join
(
installed
.
map
((
i
)
=>
this
.
uninstall
(
i
))))
.
then
(()
=>
null
);
}
private
filterOutInstalled
(
extensions
:
IGalleryExtension
[]):
TPromise
<
IGalleryExtension
[]
>
{
return
this
.
getInstalled
().
then
(
local
=>
{
return
extensions
.
filter
(
extension
=>
local
.
every
(
local
=>
local
.
id
!==
extension
.
id
));
});
}
private
filterOutUnInstalled
(
extensions
:
IGalleryExtension
[]):
TPromise
<
ILocalExtension
[]
>
{
return
this
.
getInstalled
().
then
(
installed
=>
{
return
installed
.
filter
(
local
=>
extensions
.
every
(
extension
=>
extension
.
id
===
local
.
id
));
});
}
private
downloadAndInstall
(
extension
:
IGalleryExtension
):
TPromise
<
ILocalExtension
>
{
const
id
=
getExtensionId
(
extension
,
extension
.
version
);
const
metadata
=
{
id
:
extension
.
id
,
publisherId
:
extension
.
publisherId
,
publisherDisplayName
:
extension
.
publisherDisplayName
};
return
this
.
galleryService
.
download
(
extension
)
.
then
(
zipPath
=>
validate
(
zipPath
).
then
(()
=>
zipPath
))
.
then
(
zipPath
=>
this
.
installExtension
(
zipPath
,
id
,
metadata
))
.
then
(
local
=>
this
.
_onDidInstallExtension
.
fire
({
id
,
local
,
gallery
:
extension
}),
error
=>
{
this
.
_onDidInstallExtension
.
fire
({
id
,
gallery
:
extension
,
error
});
return
TPromise
.
wrapError
(
error
);
}
);
});
.
then
(
zipPath
=>
this
.
installExtension
(
zipPath
,
id
,
metadata
));
}
private
installExtension
(
zipPath
:
string
,
id
:
string
,
metadata
:
IGalleryMetadata
=
null
):
TPromise
<
ILocalExtension
>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录