@@ -23,6 +23,7 @@ import contextKeys from "../contextKeys";
23
23
import { Dependency , ResolvedDependency , Target } from "../SwiftPackage" ;
24
24
import { FolderContext } from "../FolderContext" ;
25
25
import { Version } from "../utilities/version" ;
26
+ import { existsSync } from "fs" ;
26
27
27
28
const LOADING_ICON = "loading~spin" ;
28
29
/**
@@ -449,6 +450,7 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
449
450
private activeTasks : Set < string > = new Set ( ) ;
450
451
private lastComputedNodes : TreeNode [ ] = [ ] ;
451
452
private buildPluginOutputWatcher ?: vscode . FileSystemWatcher ;
453
+ private buildPluginFolderWatcher ?: vscode . Disposable ;
452
454
453
455
onDidChangeTreeData = this . didChangeTreeDataEmitter . event ;
454
456
@@ -545,13 +547,27 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
545
547
if ( this . buildPluginOutputWatcher ) {
546
548
this . buildPluginOutputWatcher . dispose ( ) ;
547
549
}
548
- this . buildPluginOutputWatcher = vscode . workspace . createFileSystemWatcher (
549
- new vscode . RelativePattern ( folderContext . folder , ".build/plugins/outputs/{*,*/*}" )
550
- ) ;
550
+ if ( this . buildPluginFolderWatcher ) {
551
+ this . buildPluginFolderWatcher . dispose ( ) ;
552
+ }
553
+
551
554
const fire = ( ) => this . didChangeTreeDataEmitter . fire ( ) ;
552
- this . buildPluginOutputWatcher . onDidCreate ( fire ) ;
553
- this . buildPluginOutputWatcher . onDidDelete ( fire ) ;
554
- this . buildPluginOutputWatcher . onDidChange ( fire ) ;
555
+ const buildPath = path . join ( folderContext . folder . fsPath , ".build/plugins/outputs" ) ;
556
+ this . buildPluginFolderWatcher = watchForFolder (
557
+ buildPath ,
558
+ ( ) => {
559
+ this . buildPluginOutputWatcher = vscode . workspace . createFileSystemWatcher (
560
+ new vscode . RelativePattern ( buildPath , "{*,*/*}" )
561
+ ) ;
562
+ this . buildPluginOutputWatcher . onDidCreate ( fire ) ;
563
+ this . buildPluginOutputWatcher . onDidDelete ( fire ) ;
564
+ this . buildPluginOutputWatcher . onDidChange ( fire ) ;
565
+ } ,
566
+ ( ) => {
567
+ this . buildPluginOutputWatcher ?. dispose ( ) ;
568
+ fire ( ) ;
569
+ }
570
+ ) ;
555
571
}
556
572
557
573
getTreeItem ( element : TreeNode ) : vscode . TreeItem {
@@ -570,7 +586,6 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider<TreeNode> {
570
586
...this . lastComputedNodes ,
571
587
] ;
572
588
}
573
-
574
589
const nodes = await this . computeChildren ( folderContext , element ) ;
575
590
576
591
// If we're fetching the root nodes then save them in case we have an error later,
@@ -773,3 +788,35 @@ class TaskPoller implements vscode.Disposable {
773
788
}
774
789
}
775
790
}
791
+
792
+ /**
793
+ * Polls for the existence of a folder at the given path every 2.5 seconds.
794
+ * Notifies via the provided callbacks when the folder becomes available or is deleted.
795
+ */
796
+ function watchForFolder (
797
+ folderPath : string ,
798
+ onAvailable : ( ) => void ,
799
+ onDeleted : ( ) => void
800
+ ) : vscode . Disposable {
801
+ const POLL_INTERVAL = 2500 ;
802
+ let folderExists = existsSync ( folderPath ) ;
803
+
804
+ if ( folderExists ) {
805
+ onAvailable ( ) ;
806
+ }
807
+
808
+ const interval = setInterval ( ( ) => {
809
+ const nowExists = existsSync ( folderPath ) ;
810
+ if ( nowExists && ! folderExists ) {
811
+ folderExists = true ;
812
+ onAvailable ( ) ;
813
+ } else if ( ! nowExists && folderExists ) {
814
+ folderExists = false ;
815
+ onDeleted ( ) ;
816
+ }
817
+ } , POLL_INTERVAL ) ;
818
+
819
+ return {
820
+ dispose : ( ) => clearInterval ( interval ) ,
821
+ } ;
822
+ }
0 commit comments