Skip to content

Commit 063e47f

Browse files
committed
Code review changes.
1 parent caffff7 commit 063e47f

File tree

1 file changed

+75
-72
lines changed

1 file changed

+75
-72
lines changed

runner/src/mill/runner/Watching.scala

+75-72
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,7 @@ object Watching {
7474
if (alreadyStale) {
7575
enterKeyPressed = false
7676
} else {
77-
enterKeyPressed = watchAndWait(
78-
streams,
79-
watchArgs.setIdle,
80-
streams.in,
81-
watchables,
82-
watchArgs.colors,
83-
useNotify = watchArgs.useNotify,
84-
serverDir = watchArgs.serverDir
85-
)
77+
enterKeyPressed = watchAndWait(streams, streams.in, watchables, watchArgs)
8678
}
8779
}
8880
throw new IllegalStateException("unreachable")
@@ -91,14 +83,11 @@ object Watching {
9183

9284
def watchAndWait(
9385
streams: SystemStreams,
94-
setIdle: Boolean => Unit,
9586
stdin: InputStream,
9687
watched: Seq[Watchable],
97-
colors: Colors,
98-
useNotify: Boolean,
99-
serverDir: os.Path
88+
watchArgs: WatchArgs
10089
): Boolean = {
101-
setIdle(true)
90+
watchArgs.setIdle(true)
10291
val (watchedPollables, watchedPathsSeq) = watched.partitionMap {
10392
case w: Watchable.Value => Left(w)
10493
case p: Watchable.Path => Right(p)
@@ -111,82 +100,96 @@ object Watching {
111100

112101
streams.err.println {
113102
val viaFsNotify = if (useNotify) " (via fsnotify)" else ""
114-
colors.info(
103+
watchArgs.colors.info(
115104
s"Watching for changes to ${watchedPathsSeq.size} paths$viaFsNotify$watchedValueStr... (Enter to re-run, Ctrl-C to exit)"
116105
).toString
117106
}
118107

119108
def doWatch(notifiablesChanged: () => Boolean) = {
120109
val enterKeyPressed = statWatchWait(watchedPollables, stdin, notifiablesChanged)
121-
setIdle(false)
110+
watchArgs.setIdle(false)
122111
enterKeyPressed
123112
}
124113

125-
if (useNotify) Using.resource(os.write.outputStream(serverDir / "fsNotifyWatchLog")) { watchLog =>
126-
def writeToWatchLog(s: String): Unit = {
127-
watchLog.write(s.getBytes(java.nio.charset.StandardCharsets.UTF_8))
128-
watchLog.write('\n')
129-
}
114+
def doWatchPolling() =
115+
doWatch(notifiablesChanged = () => watchedPathsSeq.exists(p => !p.validate()))
130116

131-
@volatile var pathChangesDetected = false
117+
def doWatchFsNotify() = {
118+
Using.resource(os.write.outputStream(watchArgs.serverDir / "fsNotifyWatchLog")) { watchLog =>
119+
def writeToWatchLog(s: String): Unit = {
120+
watchLog.write(s.getBytes(java.nio.charset.StandardCharsets.UTF_8))
121+
watchLog.write('\n')
122+
}
132123

133-
// oslib watch only works with folders, so we have to watch the parent folders instead
124+
@volatile var pathChangesDetected = false
134125

135-
writeToWatchLog(s"[watched-paths:unfiltered] ${watchedPathsSet.toSeq.sorted.mkString("\n")}")
126+
// oslib watch only works with folders, so we have to watch the parent folders instead
136127

137-
val workspaceRoot = mill.api.WorkspaceRoot.workspaceRoot
128+
writeToWatchLog(
129+
s"[watched-paths:unfiltered] ${watchedPathsSet.toSeq.sorted.mkString("\n")}"
130+
)
138131

139-
/** Paths that are descendants of [[workspaceRoot]]. */
140-
val pathsUnderWorkspaceRoot = watchedPathsSet.filter { path =>
141-
val isUnderWorkspaceRoot = path.startsWith(workspaceRoot)
142-
if (!isUnderWorkspaceRoot) {
143-
streams.err.println(colors.error(
144-
s"Watched path $path is outside workspace root $workspaceRoot, this is unsupported."
145-
).toString())
146-
}
147-
148-
isUnderWorkspaceRoot
149-
}
132+
val workspaceRoot = mill.api.WorkspaceRoot.workspaceRoot
150133

151-
// If I have 'root/a/b/c'
152-
//
153-
// Then I want to watch:
154-
// root/a/b/c
155-
// root/a/b
156-
// root/a
157-
// root
158-
val filterPaths = pathsUnderWorkspaceRoot.flatMap { path =>
159-
path.relativeTo(workspaceRoot).segments.inits.map(segments => workspaceRoot / segments)
160-
}
161-
writeToWatchLog(s"[watched-paths:filtered] ${filterPaths.toSeq.sorted.mkString("\n")}")
162-
163-
Using.resource(os.watch.watch(
164-
// Just watch the root folder
165-
Seq(workspaceRoot),
166-
filter = path => {
167-
val shouldBeWatched =
168-
filterPaths.contains(path) || watchedPathsSet.exists(watchedPath => path.startsWith(watchedPath))
169-
writeToWatchLog(s"[filter] (shouldBeWatched=$shouldBeWatched) $path")
170-
shouldBeWatched
171-
},
172-
onEvent = changedPaths => {
173-
// Make sure that the changed paths are actually the ones in our watch list and not some adjacent files in the
174-
// same folder
175-
val hasWatchedPath =
176-
changedPaths.exists(p => watchedPathsSet.exists(watchedPath => p.startsWith(watchedPath)))
177-
writeToWatchLog(s"[changed-paths] (hasWatchedPath=$hasWatchedPath) ${changedPaths.mkString("\n")}")
178-
if (hasWatchedPath) {
179-
pathChangesDetected = true
134+
/** Paths that are descendants of [[workspaceRoot]]. */
135+
val pathsUnderWorkspaceRoot = watchedPathsSet.filter { path =>
136+
val isUnderWorkspaceRoot = path.startsWith(workspaceRoot)
137+
if (!isUnderWorkspaceRoot) {
138+
streams.err.println(watchArgs.colors.error(
139+
s"Watched path $path is outside workspace root $workspaceRoot, this is unsupported."
140+
).toString())
180141
}
181-
},
182-
logger = (eventType, data) => writeToWatchLog(s"[watch:event] $eventType: ${pprint.apply(data).plainText}")
183-
)) { _ =>
184-
doWatch(notifiablesChanged = () => pathChangesDetected)
142+
143+
isUnderWorkspaceRoot
144+
}
145+
146+
// If I have 'root/a/b/c'
147+
//
148+
// Then I want to watch:
149+
// root/a/b/c
150+
// root/a/b
151+
// root/a
152+
// root
153+
val filterPaths = pathsUnderWorkspaceRoot.flatMap { path =>
154+
path.relativeTo(workspaceRoot).segments.inits.map(segments => workspaceRoot / segments)
155+
}
156+
writeToWatchLog(s"[watched-paths:filtered] ${filterPaths.toSeq.sorted.mkString("\n")}")
157+
158+
Using.resource(os.watch.watch(
159+
// Just watch the root folder
160+
Seq(workspaceRoot),
161+
filter = path => {
162+
val shouldBeWatched =
163+
filterPaths.contains(path) || watchedPathsSet.exists(watchedPath =>
164+
path.startsWith(watchedPath)
165+
)
166+
writeToWatchLog(s"[filter] (shouldBeWatched=$shouldBeWatched) $path")
167+
shouldBeWatched
168+
},
169+
onEvent = changedPaths => {
170+
// Make sure that the changed paths are actually the ones in our watch list and not some adjacent files in the
171+
// same folder
172+
val hasWatchedPath =
173+
changedPaths.exists(p =>
174+
watchedPathsSet.exists(watchedPath => p.startsWith(watchedPath))
175+
)
176+
writeToWatchLog(
177+
s"[changed-paths] (hasWatchedPath=$hasWatchedPath) ${changedPaths.mkString("\n")}"
178+
)
179+
if (hasWatchedPath) {
180+
pathChangesDetected = true
181+
}
182+
},
183+
logger = (eventType, data) =>
184+
writeToWatchLog(s"[watch:event] $eventType: ${pprint.apply(data).plainText}")
185+
)) { _ =>
186+
doWatch(notifiablesChanged = () => pathChangesDetected)
187+
}
185188
}
186189
}
187-
else {
188-
doWatch(notifiablesChanged = () => watchedPathsSeq.exists(p => !p.validate()))
189-
}
190+
191+
if (watchArgs.useNotify) doWatchFsNotify()
192+
else doWatchPolling()
190193
}
191194

192195
/**

0 commit comments

Comments
 (0)