Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
48a286f9
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
48a286f9
编写于
9月 12, 2017
作者:
D
Dirk Baeumer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Making tasks.json parser workspace folder aware
上级
655527d1
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
174 addition
and
45 deletion
+174
-45
src/vs/workbench/parts/tasks/common/tasks.ts
src/vs/workbench/parts/tasks/common/tasks.ts
+6
-0
src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
...rkbench/parts/tasks/electron-browser/task.contribution.ts
+151
-9
src/vs/workbench/parts/tasks/node/taskConfiguration.ts
src/vs/workbench/parts/tasks/node/taskConfiguration.ts
+14
-33
src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts
...h/parts/tasks/test/electron-browser/configuration.test.ts
+3
-3
未找到文件。
src/vs/workbench/parts/tasks/common/tasks.ts
浏览文件 @
48a286f9
...
...
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
*
as
Types
from
'
vs/base/common/types
'
;
import
{
IJSONSchemaMap
}
from
'
vs/base/common/jsonSchema
'
;
...
...
@@ -221,7 +222,12 @@ export namespace TaskSourceKind {
export
const
Composite
:
'
composite
'
=
'
composite
'
;
}
export
interface
WorkspaceFolder
{
uri
:
URI
;
}
export
interface
TaskSourceConfigElement
{
workspaceFolder
:
WorkspaceFolder
;
file
:
string
;
index
:
number
;
element
:
any
;
...
...
src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts
浏览文件 @
48a286f9
...
...
@@ -76,7 +76,7 @@ import { Scope, IActionBarRegistry, Extensions as ActionBarExtensions } from 'vs
import
{
ITerminalService
}
from
'
vs/workbench/parts/terminal/common/terminal
'
;
import
{
ITaskSystem
,
ITaskResolver
,
ITaskSummary
,
ITaskExecuteResult
,
TaskExecuteKind
,
TaskError
,
TaskErrors
,
TaskSystemEvents
,
TaskTerminateResponse
}
from
'
vs/workbench/parts/tasks/common/taskSystem
'
;
import
{
Task
,
CustomTask
,
ConfiguringTask
,
ContributedTask
,
CompositeTask
,
TaskSet
,
TaskGroup
,
ExecutionEngine
,
JsonSchemaVersion
,
TaskSourceKind
,
TaskIdentifier
}
from
'
vs/workbench/parts/tasks/common/tasks
'
;
import
{
Task
,
CustomTask
,
ConfiguringTask
,
ContributedTask
,
CompositeTask
,
TaskSet
,
TaskGroup
,
ExecutionEngine
,
JsonSchemaVersion
,
TaskSourceKind
,
TaskIdentifier
,
WorkspaceFolder
}
from
'
vs/workbench/parts/tasks/common/tasks
'
;
import
{
ITaskService
,
TaskServiceEvents
,
ITaskProvider
,
TaskEvent
,
RunOptions
,
CustomizationProperties
}
from
'
vs/workbench/parts/tasks/common/taskService
'
;
import
{
templates
as
taskTemplates
}
from
'
vs/workbench/parts/tasks/common/taskTemplates
'
;
...
...
@@ -618,7 +618,12 @@ interface WorkspaceTaskResult {
hasErrors
:
boolean
;
}
interface
WorkspaceConfigurationResult
{
interface
WorkspaceFolderTaskResult
extends
WorkspaceTaskResult
{
workspaceFolder
:
WorkspaceFolder
;
}
interface
WorkspaceFolderConfigurationResult
{
workspaceFolder
:
WorkspaceFolder
;
config
:
TaskConfig
.
ExternalTaskRunnerConfiguration
;
hasErrors
:
boolean
;
}
...
...
@@ -657,6 +662,9 @@ class TaskService extends EventEmitter implements ITaskService {
private
quickOpenService
:
IQuickOpenService
;
private
_configHasErrors
:
boolean
;
private
_schemaVersion
:
JsonSchemaVersion
;
private
_executionEngine
:
ExecutionEngine
;
private
_workspaceFolders
:
WorkspaceFolder
[];
private
_providers
:
Map
<
number
,
ITaskProvider
>
;
private
_workspaceTasksPromise
:
TPromise
<
WorkspaceTaskResult
>
;
...
...
@@ -736,6 +744,7 @@ class TaskService extends EventEmitter implements ITaskService {
);
}
});
this
.
updateWorkspaceFolders
();
lifecycleService
.
onWillShutdown
(
event
=>
event
.
veto
(
this
.
beforeShutdown
()));
this
.
registerCommands
();
}
...
...
@@ -1449,8 +1458,9 @@ class TaskService extends EventEmitter implements ITaskService {
});
}
private
computeWorkspaceTasks
():
TPromise
<
WorkspaceTaskResult
>
{
let
configPromise
:
TPromise
<
WorkspaceConfigurationResult
>
;
/*
private computeWorkspaceTasks2(): TPromise<WorkspaceTaskResult> {
let configPromise: TPromise<WorkspaceFolderConfigurationResult>;
{
let { config, hasParseErrors } = this.getConfiguration();
if (hasParseErrors) {
...
...
@@ -1461,7 +1471,7 @@ class TaskService extends EventEmitter implements ITaskService {
engine = TaskConfig.ExecutionEngine.from(config);
if (engine === ExecutionEngine.Process) {
if (this.hasDetectorSupport(config)) {
configPromise
=
new
ProcessRunnerDetector
(
this
.
fileService
,
this
.
contextService
,
this
.
configurationResolverService
,
config
).
detect
(
true
).
then
((
value
):
WorkspaceConfigurationResult
=>
{
configPromise = new ProcessRunnerDetector(this.fileService, this.contextService, this.configurationResolverService, config).detect(true).then((value): Workspace
Folder
ConfigurationResult => {
let hasErrors = this.printStderr(value.stderr);
let detectedConfig = value.config;
if (!detectedConfig) {
...
...
@@ -1529,17 +1539,145 @@ class TaskService extends EventEmitter implements ITaskService {
});
});
}
*/
private
computeWorkspaceTasks
():
TPromise
<
Map
<
string
,
WorkspaceFolderTaskResult
>>
{
if
(
this
.
_workspaceFolders
.
length
===
0
)
{
return
TPromise
.
as
(
new
Map
<
string
,
WorkspaceFolderTaskResult
>
());
}
else
{
let
promises
:
TPromise
<
WorkspaceFolderTaskResult
>
[]
=
[];
for
(
let
folder
of
this
.
_workspaceFolders
)
{
promises
.
push
(
this
.
computeWorkspaceFolderTasks
(
folder
).
then
((
value
)
=>
value
,
()
=>
undefined
));
}
return
TPromise
.
join
(
promises
).
then
((
values
)
=>
{
let
result
=
new
Map
<
string
,
WorkspaceFolderTaskResult
>
();
for
(
let
value
of
values
)
{
if
(
value
)
{
result
.
set
(
value
.
workspaceFolder
.
uri
.
toString
(),
value
);
}
}
return
result
;
});
}
}
private
computeWorkspaceFolderTasks
(
workspaceFolder
:
WorkspaceFolder
):
TPromise
<
WorkspaceFolderTaskResult
>
{
return
(
this
.
_executionEngine
===
ExecutionEngine
.
Process
?
this
.
computeLegacyConfiguration
(
workspaceFolder
)
:
this
.
computeConfiguration
(
workspaceFolder
)).
then
((
workspaceFolderConfiguration
)
=>
{
if
(
!
workspaceFolderConfiguration
||
!
workspaceFolderConfiguration
.
config
||
workspaceFolderConfiguration
.
hasErrors
)
{
return
TPromise
.
as
({
workspaceFolder
,
set
:
undefined
,
configurations
:
undefined
,
hasErrors
:
workspaceFolderConfiguration
?
workspaceFolderConfiguration
.
hasErrors
:
false
});
}
return
ProblemMatcherRegistry
.
onReady
().
then
(():
WorkspaceFolderTaskResult
=>
{
let
problemReporter
=
new
ProblemReporter
(
this
.
_outputChannel
);
let
parseResult
=
TaskConfig
.
parse
(
workspaceFolder
,
workspaceFolderConfiguration
.
config
,
problemReporter
);
let
hasErrors
=
false
;
if
(
!
parseResult
.
validationStatus
.
isOK
())
{
hasErrors
=
true
;
this
.
showOutput
();
}
if
(
problemReporter
.
status
.
isFatal
())
{
problemReporter
.
fatal
(
nls
.
localize
(
'
TaskSystem.configurationErrors
'
,
'
Error: the provided task configuration has validation errors and can
\'
t not be used. Please correct the errors first.
'
));
return
{
workspaceFolder
,
set
:
undefined
,
configurations
:
undefined
,
hasErrors
};
}
let
customizedTasks
:
{
byIdentifier
:
IStringDictionary
<
ConfiguringTask
>
;
};
if
(
parseResult
.
configured
&&
parseResult
.
configured
.
length
>
0
)
{
customizedTasks
=
{
byIdentifier
:
Object
.
create
(
null
)
};
for
(
let
task
of
parseResult
.
configured
)
{
customizedTasks
.
byIdentifier
[
task
.
configures
.
_key
]
=
task
;
}
}
return
{
workspaceFolder
,
set
:
{
tasks
:
parseResult
.
custom
},
configurations
:
customizedTasks
,
hasErrors
};
});
});
}
private
computeConfiguration
(
workspaceFolder
:
WorkspaceFolder
):
TPromise
<
WorkspaceFolderConfigurationResult
>
{
let
{
config
,
hasParseErrors
}
=
this
.
getConfiguration
(
workspaceFolder
);
return
TPromise
.
as
<
WorkspaceFolderConfigurationResult
>
({
workspaceFolder
,
config
,
hasErrors
:
hasParseErrors
});
}
private
computeLegacyConfiguration
(
workspaceFolder
:
WorkspaceFolder
):
TPromise
<
WorkspaceFolderConfigurationResult
>
{
let
{
config
,
hasParseErrors
}
=
this
.
getConfiguration
(
workspaceFolder
);
if
(
hasParseErrors
)
{
return
TPromise
.
as
({
workspaceFolder
:
workspaceFolder
,
hasErrors
:
true
,
config
:
undefined
});
}
if
(
config
)
{
if
(
this
.
hasDetectorSupport
(
config
))
{
return
new
ProcessRunnerDetector
(
this
.
fileService
,
this
.
contextService
,
this
.
configurationResolverService
,
config
).
detect
(
true
).
then
((
value
):
WorkspaceFolderConfigurationResult
=>
{
let
hasErrors
=
this
.
printStderr
(
value
.
stderr
);
let
detectedConfig
=
value
.
config
;
if
(
!
detectedConfig
)
{
return
{
workspaceFolder
,
config
,
hasErrors
};
}
let
result
:
TaskConfig
.
ExternalTaskRunnerConfiguration
=
Objects
.
clone
(
config
);
let
configuredTasks
:
IStringDictionary
<
TaskConfig
.
CustomTask
>
=
Object
.
create
(
null
);
if
(
!
result
.
tasks
)
{
if
(
detectedConfig
.
tasks
)
{
result
.
tasks
=
detectedConfig
.
tasks
;
}
}
else
{
result
.
tasks
.
forEach
(
task
=>
configuredTasks
[
task
.
taskName
]
=
task
);
detectedConfig
.
tasks
.
forEach
((
task
)
=>
{
if
(
!
configuredTasks
[
task
.
taskName
])
{
result
.
tasks
.
push
(
task
);
}
});
}
return
{
workspaceFolder
,
config
:
result
,
hasErrors
};
});
}
else
{
return
TPromise
.
as
({
workspaceFolder
,
config
,
hasErrors
:
false
});
}
}
else
{
return
new
ProcessRunnerDetector
(
this
.
fileService
,
this
.
contextService
,
this
.
configurationResolverService
).
detect
(
true
).
then
((
value
)
=>
{
let
hasErrors
=
this
.
printStderr
(
value
.
stderr
);
return
{
workspaceFolder
,
config
:
value
.
config
,
hasErrors
};
});
}
}
private
updateWorkspaceFolders
():
void
{
if
(
this
.
contextService
.
hasFolderWorkspace
())
{
let
workspaceFolder
=
{
uri
:
this
.
contextService
.
getWorkspace
().
roots
[
0
]
};
this
.
_workspaceFolders
=
[
workspaceFolder
];
this
.
_executionEngine
=
this
.
computeExecutionEngine
(
workspaceFolder
);
this
.
_schemaVersion
=
this
.
computeJsonSchemaVersion
(
workspaceFolder
);
}
else
if
(
this
.
contextService
.
hasMultiFolderWorkspace
())
{
this
.
_executionEngine
=
ExecutionEngine
.
Terminal
;
this
.
_schemaVersion
=
JsonSchemaVersion
.
V2_0_0
;
this
.
_workspaceFolders
=
[];
for
(
let
folder
of
this
.
contextService
.
getWorkspace
().
roots
)
{
let
workspaceFolder
=
{
uri
:
folder
};
if
(
this
.
_schemaVersion
===
this
.
computeJsonSchemaVersion
(
workspaceFolder
))
{
this
.
_workspaceFolders
.
push
(
workspaceFolder
);
}
else
{
this
.
_outputChannel
.
append
(
nls
.
localize
(
'
taskService.ignoreingFolder
'
,
'
Ignoring task configurations for workspace folder {0}. Multi root folder support requires that all folders use task version 2.0.
'
,
folder
.
fsPath
));
}
}
}
else
{
this
.
_workspaceFolders
=
[];
this
.
_executionEngine
=
ExecutionEngine
.
Terminal
;
this
.
_schemaVersion
=
JsonSchemaVersion
.
V2_0_0
;
}
}
private
getExecutionEngine
(
):
ExecutionEngine
{
let
{
config
}
=
this
.
getConfiguration
();
private
computeExecutionEngine
(
workspaceFolder
:
WorkspaceFolder
):
ExecutionEngine
{
let
{
config
}
=
this
.
getConfiguration
(
workspaceFolder
);
if
(
!
config
)
{
return
ExecutionEngine
.
_default
;
}
return
TaskConfig
.
ExecutionEngine
.
from
(
config
);
}
private
getJsonSchemaVersion
(
):
JsonSchemaVersion
{
let
{
config
}
=
this
.
getConfiguration
();
private
computeJsonSchemaVersion
(
workspaceFolder
:
WorkspaceFolder
):
JsonSchemaVersion
{
let
{
config
}
=
this
.
getConfiguration
(
workspaceFolder
);
if
(
!
config
)
{
return
JsonSchemaVersion
.
V2_0_0
;
}
...
...
@@ -1548,6 +1686,10 @@ class TaskService extends EventEmitter implements ITaskService {
private
getConfiguration
():
{
config
:
TaskConfig
.
ExternalTaskRunnerConfiguration
;
hasParseErrors
:
boolean
}
{
let
result
=
this
.
contextService
.
getWorkbenchState
()
!==
WorkbenchState
.
EMPTY
?
this
.
configurationService
.
getConfiguration
<
TaskConfig
.
ExternalTaskRunnerConfiguration
>
(
'
tasks
'
,
{
resource
:
this
.
contextService
.
getWorkspace
().
folders
[
0
]
})
:
undefined
;
private
getConfiguration
(
workspaceFolder
:
WorkspaceFolder
):
{
config
:
TaskConfig
.
ExternalTaskRunnerConfiguration
;
hasParseErrors
:
boolean
}
{
let
result
=
this
.
contextService
.
hasWorkspace
()
?
this
.
configurationService
.
getConfiguration
<
TaskConfig
.
ExternalTaskRunnerConfiguration
>
(
'
tasks
'
,
{
resource
:
workspaceFolder
.
uri
})
:
undefined
;
if
(
!
result
)
{
return
{
config
:
undefined
,
hasParseErrors
:
false
};
}
...
...
src/vs/workbench/parts/tasks/node/taskConfiguration.ts
浏览文件 @
48a286f9
...
...
@@ -561,6 +561,7 @@ function _freeze<T>(this: void, target: T, properties: MetaData<T, any>[]): Read
}
interface
ParseContext
{
workspaceFolder
:
Tasks
.
WorkspaceFolder
;
problemReporter
:
IProblemReporter
;
namedProblemMatchers
:
IStringDictionary
<
NamedProblemMatcher
>
;
uuidMap
:
UUIDMap
;
...
...
@@ -1160,6 +1161,7 @@ namespace ConfiguringTask {
}
let
taskIdentifier
=
TaskIdentifier
.
from
(
identifier
);
let
configElement
:
Tasks
.
TaskSourceConfigElement
=
{
workspaceFolder
:
context
.
workspaceFolder
,
file
:
'
.vscode
\\
tasks.json
'
,
index
,
element
:
external
...
...
@@ -1678,10 +1680,12 @@ class UUIDMap {
class
ConfigurationParser
{
private
workspaceFolder
:
Tasks
.
WorkspaceFolder
;
private
problemReporter
:
IProblemReporter
;
private
uuidMap
:
UUIDMap
;
constructor
(
problemReporter
:
IProblemReporter
,
uuidMap
:
UUIDMap
)
{
constructor
(
workspaceFolder
:
Tasks
.
WorkspaceFolder
,
problemReporter
:
IProblemReporter
,
uuidMap
:
UUIDMap
)
{
this
.
workspaceFolder
=
workspaceFolder
;
this
.
problemReporter
=
problemReporter
;
this
.
uuidMap
=
uuidMap
;
}
...
...
@@ -1693,6 +1697,7 @@ class ConfigurationParser {
this
.
problemReporter
.
clearOutput
();
}
let
context
:
ParseContext
=
{
workspaceFolder
:
this
.
workspaceFolder
,
problemReporter
:
this
.
problemReporter
,
uuidMap
:
this
.
uuidMap
,
namedProblemMatchers
:
undefined
,
...
...
@@ -1783,11 +1788,16 @@ class ConfigurationParser {
}
}
let
uuidMap
:
UUIDMap
=
new
UUIDMap
();
export
function
parse
(
configuration
:
ExternalTaskRunnerConfiguration
,
logger
:
IProblemReporter
):
ParseResult
{
let
uuidMaps
:
Map
<
string
,
UUIDMap
>
=
new
Map
();
export
function
parse
(
workspaceFolder
:
Tasks
.
WorkspaceFolder
,
configuration
:
ExternalTaskRunnerConfiguration
,
logger
:
IProblemReporter
):
ParseResult
{
let
uuidMap
=
uuidMaps
.
get
(
workspaceFolder
.
uri
.
toString
());
if
(
!
uuidMap
)
{
uuidMap
=
new
UUIDMap
();
uuidMaps
.
set
(
workspaceFolder
.
uri
.
toString
(),
uuidMap
);
}
try
{
uuidMap
.
start
();
return
(
new
ConfigurationParser
(
logger
,
uuidMap
)).
run
(
configuration
);
return
(
new
ConfigurationParser
(
workspaceFolder
,
logger
,
uuidMap
)).
run
(
configuration
);
}
finally
{
uuidMap
.
finish
();
}
...
...
@@ -1801,35 +1811,6 @@ export function getTaskIdentifier(value: TaskIdentifier): Tasks.TaskIdentifier {
return
TaskIdentifier
.
from
(
value
);
}
export
function
findTaskIndex
(
fileConfig
:
ExternalTaskRunnerConfiguration
,
task
:
Tasks
.
Task
):
number
{
if
(
!
fileConfig
||
!
fileConfig
.
tasks
)
{
return
undefined
;
}
if
(
fileConfig
.
tasks
.
length
===
0
)
{
return
-
1
;
}
let
localMap
=
new
UUIDMap
(
uuidMap
);
let
context
:
ParseContext
=
{
problemReporter
:
this
.
problemReporter
,
uuidMap
:
localMap
,
namedProblemMatchers
:
undefined
,
engine
:
ExecutionEngine
.
from
(
fileConfig
),
schemaVersion
:
JsonSchemaVersion
.
from
(
fileConfig
)
};
try
{
localMap
.
start
();
let
tasks
=
TaskParser
.
quickParse
(
fileConfig
.
tasks
,
context
);
for
(
let
i
=
0
;
i
<
tasks
.
length
;
i
++
)
{
if
(
task
.
_id
===
tasks
[
i
].
_id
)
{
return
i
;
}
}
return
-
1
;
}
finally
{
localMap
.
finish
();
}
}
/*
class VersionConverter {
constructor(private problemReporter: IProblemReporter) {
...
...
src/vs/workbench/parts/tasks/test/electron-browser/configuration.test.ts
浏览文件 @
48a286f9
...
...
@@ -177,7 +177,7 @@ class CustomTaskBuilder {
this
.
commandBuilder
=
new
CommandConfigurationBuilder
(
this
,
command
);
this
.
result
=
{
_id
:
name
,
_source
:
{
kind
:
Tasks
.
TaskSourceKind
.
Workspace
,
label
:
'
workspace
'
,
config
:
{
element
:
undefined
,
index
:
-
1
,
file
:
'
.vscode/tasks.json
'
}
},
_source
:
{
kind
:
Tasks
.
TaskSourceKind
.
Workspace
,
label
:
'
workspace
'
,
config
:
{
workspaceFolder
:
{
uri
:
undefined
},
element
:
undefined
,
index
:
-
1
,
file
:
'
.vscode/tasks.json
'
}
},
_label
:
name
,
type
:
'
custom
'
,
identifier
:
name
,
...
...
@@ -347,7 +347,7 @@ class PatternBuilder {
function
testDefaultProblemMatcher
(
external
:
ExternalTaskRunnerConfiguration
,
resolved
:
number
)
{
let
reporter
=
new
ProblemReporter
();
let
result
=
parse
(
external
,
reporter
);
let
result
=
parse
(
external
,
{
uri
:
undefined
},
reporter
);
assert
.
ok
(
!
reporter
.
receivedMessage
);
assert
.
strictEqual
(
result
.
custom
.
length
,
1
);
let
task
=
result
.
custom
[
0
];
...
...
@@ -358,7 +358,7 @@ function testDefaultProblemMatcher(external: ExternalTaskRunnerConfiguration, re
function
testConfiguration
(
external
:
ExternalTaskRunnerConfiguration
,
builder
:
ConfiguationBuilder
):
void
{
builder
.
done
();
let
reporter
=
new
ProblemReporter
();
let
result
=
parse
(
external
,
reporter
);
let
result
=
parse
(
external
,
{
uri
:
undefined
},
reporter
);
if
(
reporter
.
receivedMessage
)
{
assert
.
ok
(
false
,
reporter
.
lastMessage
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录