@@ -4,10 +4,15 @@ import java.util.concurrent.TimeUnit
4
4
5
5
import scala .concurrent .ExecutionContext
6
6
import scala .concurrent .Future
7
+ import scala .concurrent .Promise
7
8
8
9
import scala .meta .internal .builds .Digest .Status
9
10
import scala .meta .internal .metals .BuildInfo
11
+ import scala .meta .internal .metals .CancelSwitch
12
+ import scala .meta .internal .metals .CancelableFuture
10
13
import scala .meta .internal .metals .Confirmation
14
+ import scala .meta .internal .metals .Interruptable
15
+ import scala .meta .internal .metals .Interruptable ._
11
16
import scala .meta .internal .metals .Messages ._
12
17
import scala .meta .internal .metals .MetalsEnrichments ._
13
18
import scala .meta .internal .metals .Tables
@@ -37,14 +42,14 @@ final class BloopInstall(
37
42
38
43
def runUnconditionally (
39
44
buildTool : BloopInstallProvider
40
- ): Future [WorkspaceLoadedStatus ] = {
45
+ ): CancelableFuture [WorkspaceLoadedStatus ] = {
41
46
buildTool.bloopInstall(
42
47
workspace,
43
48
args => {
44
49
scribe.info(s " running ' ${args.mkString(" " )}' " )
45
50
val process =
46
51
runArgumentsUnconditionally(buildTool, args, userConfig().javaHome)
47
- process.foreach { e =>
52
+ process.future. foreach { e =>
48
53
if (e.isFailed) {
49
54
// Record the exact command that failed to help troubleshooting.
50
55
scribe.error(s " $buildTool command failed: ${args.mkString(" " )}" )
@@ -59,7 +64,7 @@ final class BloopInstall(
59
64
buildTool : BloopInstallProvider ,
60
65
args : List [String ],
61
66
javaHome : Option [String ],
62
- ): Future [WorkspaceLoadedStatus ] = {
67
+ ): CancelableFuture [WorkspaceLoadedStatus ] = {
63
68
persistChecksumStatus(Status .Started , buildTool)
64
69
val processFuture = shellRunner
65
70
.run(
@@ -81,7 +86,7 @@ final class BloopInstall(
81
86
case ExitCodes .Cancel => WorkspaceLoadedStatus .Cancelled
82
87
case result => WorkspaceLoadedStatus .Failed (result)
83
88
}
84
- processFuture.foreach { result =>
89
+ processFuture.future. foreach { result =>
85
90
try result.toChecksumStatus.foreach(persistChecksumStatus(_, buildTool))
86
91
catch {
87
92
case _ : InterruptedException =>
@@ -112,35 +117,36 @@ final class BloopInstall(
112
117
def runIfApproved (
113
118
buildTool : BloopInstallProvider ,
114
119
digest : String ,
115
- ): Future [WorkspaceLoadedStatus ] =
120
+ ): CancelableFuture [WorkspaceLoadedStatus ] =
116
121
synchronized {
117
122
oldInstallResult(digest) match {
118
123
case Some (result)
119
124
if result != WorkspaceLoadedStatus .Duplicate (Status .Requested ) =>
120
125
scribe.info(s " skipping build import with status ' ${result.name}' " )
121
- Future .successful(result)
126
+ CancelableFuture .successful(result)
122
127
case _ =>
123
128
if (userConfig().shouldAutoImportNewProject) {
124
129
runUnconditionally(buildTool)
125
130
} else {
126
131
scribe.debug(" Awaiting user response..." )
127
- for {
132
+ implicit val cancelSwitch = CancelSwitch (Promise [Unit ]())
133
+ (for {
128
134
userResponse <- requestImport(
129
135
buildTools,
130
136
buildTool,
131
137
languageClient,
132
138
digest,
133
- )
139
+ ).withInterrupt
134
140
installResult <- {
135
141
if (userResponse.isYes) {
136
- runUnconditionally(buildTool)
142
+ runUnconditionally(buildTool).withInterrupt
137
143
} else {
138
144
// Don't spam the user with requests during rapid build changes.
139
145
notification.dismiss(2 , TimeUnit .MINUTES )
140
- Future .successful(WorkspaceLoadedStatus .Rejected )
146
+ Interruptable .successful(WorkspaceLoadedStatus .Rejected )
141
147
}
142
148
}
143
- } yield installResult
149
+ } yield installResult).toCancellable
144
150
}
145
151
}
146
152
}
0 commit comments