Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace nsfw with @parcel/watcher #12784

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@

- [Previous Changelogs](https://github.com/eclipse-theia/theia/tree/master/doc/changelogs/)

## v1.41.0 - 08/31/2023

<a name="breaking_changes_1.41.0">[Breaking Changes:](#breaking_changes_1.41.0)</a>

- [core/filesystem] The `nsfw` package has been replaced with `@parcel/watcher`. Services that used `nsfw` previously, such as the `NsfwWatcher` (now `ParcelWatcher`), have been renamed to reflect this change.

## v1.40.0 - 07/27/2023

- [application-package] bumped the default supported VS Code API from `1.78.0` to `1.79.0` [#12764](https://github.com/eclipse-theia/theia/pull/12764) - Contributed on behalf of STMicroelectronics.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ const production = mode === 'production';
const commonJsLibraries = {};
for (const [entryPointName, entryPointPath] of Object.entries({
${this.ifPackage('@theia/plugin-ext', "'backend-init-theia': '@theia/plugin-ext/lib/hosted/node/scanners/backend-init-theia',")}
${this.ifPackage('@theia/filesystem', "'nsfw-watcher': '@theia/filesystem/lib/node/nsfw-watcher',")}
${this.ifPackage('@theia/filesystem', "'parcel-watcher': '@theia/filesystem/lib/node/parcel-watcher',")}
${this.ifPackage('@theia/plugin-ext-vscode', "'plugin-vscode-init': '@theia/plugin-ext-vscode/lib/node/plugin-vscode-init',")}
})) {
commonJsLibraries[entryPointName] = {
Expand Down
1 change: 0 additions & 1 deletion dev-packages/application-manager/src/rebuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ type NodeABI = string | number;

export const DEFAULT_MODULES = [
'node-pty',
'nsfw',
'native-keymap',
'find-git-repositories',
'drivelist',
Expand Down
1 change: 1 addition & 0 deletions dev-packages/native-webpack-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"watch": "theiaext watch"
},
"dependencies": {
"detect-libc": "^2.0.2",
"temp": "^0.9.1",
"webpack": "^5.76.0"
}
Expand Down
17 changes: 16 additions & 1 deletion dev-packages/native-webpack-plugin/src/native-webpack-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const REQUIRE_RIPGREP = '@vscode/ripgrep';
const REQUIRE_VSCODE_WINDOWS_CA_CERTS = '@vscode/windows-ca-certs';
const REQUIRE_BINDINGS = 'bindings';
const REQUIRE_KEYMAPPING = './build/Release/keymapping';
const REQUIRE_PARCEL_WATCHER = './build/Release/watcher.node';

export interface NativeWebpackPluginOptions {
out: string;
Expand Down Expand Up @@ -67,7 +68,8 @@ export class NativeWebpackPlugin {
[REQUIRE_RIPGREP]: ripgrepFile,
[REQUIRE_BINDINGS]: bindingsFile,
[REQUIRE_KEYMAPPING]: keymappingFile,
[REQUIRE_VSCODE_WINDOWS_CA_CERTS]: windowsCaCertsFile
[REQUIRE_VSCODE_WINDOWS_CA_CERTS]: windowsCaCertsFile,
[REQUIRE_PARCEL_WATCHER]: findNativeWatcherFile()
};
});
compiler.hooks.normalModuleFactory.tap(
Expand Down Expand Up @@ -135,6 +137,19 @@ export class NativeWebpackPlugin {
}
}

function findNativeWatcherFile(): string {
let name = `@parcel/watcher-${process.platform}-${process.arch}`;
if (process.platform === 'linux') {
const { MUSL, family } = require('detect-libc');
if (family === MUSL) {
name += '-musl';
} else {
name += '-glibc';
}
}
return require.resolve(name);
}

function buildFile(root: string, name: string, content: string): string {
const tmpFile = path.join(root, name);
fs.writeFileSync(tmpFile, content);
Expand Down
11 changes: 4 additions & 7 deletions dev-packages/private-ext-scripts/theia-ts-clean.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
const _glob = require('glob');
const debug = require('debug')('ts-clean');
const fs = require('fs');
const nsfw = require('nsfw');
const parcelWatcher = require('@parcel/watcher');
const path = require('path');
const util = require('util');
const yargs = require('yargs');
Expand Down Expand Up @@ -121,13 +121,11 @@ async function tsClean() {
*/
async function tsCleanWatch(src, dst, dry) {
await tsCleanRun(src, dst, dry);
const watcher = await nsfw(src, async events => {
await parcelWatcher.subscribe(src, async (_err, events) => {
for (const event of events) {
let absolute;
if (event.action === nsfw.actions.DELETED) {
absolute = path.resolve(event.directory, event.file);
} else if (event.action === nsfw.actions.RENAMED) {
absolute = path.resolve(event.directory, event.oldFile);
if (event.type === 'delete') {
absolute = event.path;
} else {
continue;
}
Expand All @@ -143,7 +141,6 @@ async function tsCleanWatch(src, dst, dry) {
}));
}
});
await watcher.start();
}

/**
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
"lerna": "^6.0.1",
"mkdirp": "^0.5.0",
"node-gyp": "^9.0.0",
"nsfw": "^2.2.4",
"nyc": "^15.0.0",
"puppeteer": "^19.7.2",
"puppeteer-core": "^19.7.2",
Expand Down
6 changes: 3 additions & 3 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ export class SomeClass {
- `react-virtuoso` (from [`react-virtuoso@^2.17.0`](https://www.npmjs.com/package/react-virtuoso))
- `vscode-languageserver-protocol` (from [`vscode-languageserver-protocol@^3.17.2`](https://www.npmjs.com/package/vscode-languageserver-protocol))
- `vscode-uri` (from [`vscode-uri@^2.1.1`](https://www.npmjs.com/package/vscode-uri))
- `@parcel/watcher` (from [`@parcel/watcher@^2.2.0`](https://www.npmjs.com/package/@parcel/watcher))
- `dompurify` (from [`dompurify@^2.2.9`](https://www.npmjs.com/package/dompurify))
- `express` (from [`express@^4.16.3`](https://www.npmjs.com/package/express))
- `lodash.debounce` (from [`lodash.debounce@^4.0.8`](https://www.npmjs.com/package/lodash.debounce))
- `lodash.throttle` (from [`lodash.throttle@^4.1.1`](https://www.npmjs.com/package/lodash.throttle))
- `nsfw` (from [`nsfw@^2.2.4`](https://www.npmjs.com/package/nsfw))
- `markdown-it` (from [`markdown-it@^12.3.2`](https://www.npmjs.com/package/markdown-it))
- `react` (from [`react@^18.2.0`](https://www.npmjs.com/package/react))
- `ws` (from [`ws@^7.1.2`](https://www.npmjs.com/package/ws))
Expand Down Expand Up @@ -138,8 +138,8 @@ existing loggers. However, each log message specifies from which logger it
comes from, which can give an idea, without having to read the code:

```
root INFO [nsfw-watcher: 10734] Started watching: /Users/captain.future/git/theia/CONTRIBUTING.md
^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^
root INFO [parcel-watcher: 10734] Started watching: /Users/captain.future/git/theia/CONTRIBUTING.md
^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^
```
Where `root` is the name of the logger and `INFO` is the log level. These are optionally followed by the name of a child process and the process ID.

Expand Down
4 changes: 2 additions & 2 deletions packages/core/README_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ existing loggers. However, each log message specifies from which logger it
comes from, which can give an idea, without having to read the code:

```
root INFO [nsfw-watcher: 10734] Started watching: /Users/captain.future/git/theia/CONTRIBUTING.md
^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^
root INFO [parcel-watcher: 10734] Started watching: /Users/captain.future/git/theia/CONTRIBUTING.md
^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^
```
Where `root` is the name of the logger and `INFO` is the log level. These are optionally followed by the name of a child process and the process ID.

Expand Down
4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"typings": "lib/common/index.d.ts",
"dependencies": {
"@babel/runtime": "^7.10.0",
"@parcel/watcher": "^2.2.0",
"@phosphor/algorithm": "1",
"@phosphor/commands": "1",
"@phosphor/coreutils": "1",
Expand Down Expand Up @@ -56,7 +57,6 @@
"lodash.throttle": "^4.1.1",
"markdown-it": "^12.3.2",
"msgpackr": "^1.6.1",
"nsfw": "^2.2.4",
"p-debounce": "^2.1.0",
"perfect-scrollbar": "^1.3.0",
"react": "^18.2.0",
Expand Down Expand Up @@ -117,11 +117,11 @@
"vscode-uri"
],
"export =": [
"@parcel/watcher as parcelWatcher",
"dompurify as DOMPurify",
"express",
"lodash.debounce as debounce",
"lodash.throttle as throttle",
"nsfw",
"markdown-it as markdownit",
"react as React",
"ws as WebSocket",
Expand Down
2 changes: 2 additions & 0 deletions packages/core/shared/@parcel/watcher/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import parcelWatcher = require('@parcel/watcher');
export = parcelWatcher;
1 change: 1 addition & 0 deletions packages/core/shared/@parcel/watcher/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('@parcel/watcher');
2 changes: 0 additions & 2 deletions packages/core/shared/nsfw/index.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/core/shared/nsfw/index.js

This file was deleted.

18 changes: 10 additions & 8 deletions packages/core/src/node/logger-cli-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { injectable } from 'inversify';
import { LogLevel } from '../common/logger';
import { CliContribution } from './cli';
import * as fs from 'fs-extra';
import * as nsfw from 'nsfw';
import { subscribe } from '@parcel/watcher';
import { Event, Emitter } from '../common/event';
import * as path from 'path';

Expand Down Expand Up @@ -89,13 +89,17 @@ export class LogLevelCliContribution implements CliContribution {
}
}

protected watchLogConfigFile(filename: string): Promise<void> {
return nsfw(filename, async (events: nsfw.FileChangeEvent[]) => {
protected async watchLogConfigFile(filename: string): Promise<void> {
await subscribe(filename, async (err, events) => {
if (err) {
console.log(`Error during log file watching ${filename}: ${err}`);
return;
}
try {
for (const event of events) {
switch (event.action) {
case nsfw.actions.CREATED:
case nsfw.actions.MODIFIED:
switch (event.type) {
case 'create':
case 'update':
await this.slurpLogConfigFile(filename);
this.logConfigChangedEvent.fire(undefined);
break;
Expand All @@ -104,8 +108,6 @@ export class LogLevelCliContribution implements CliContribution {
} catch (e) {
console.error(`Error reading log config file ${filename}: ${e}`);
}
}).then((watcher: nsfw.NSFW) => {
watcher.start();
});
}

Expand Down
20 changes: 1 addition & 19 deletions packages/filesystem/src/browser/file-tree/file-tree-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { FileStatNode, DirNode, FileNode } from './file-tree';
import { LocationService } from '../location';
import { LabelProvider } from '@theia/core/lib/browser/label-provider';
import { FileService } from '../file-service';
import { FileOperationError, FileOperationResult, FileChangesEvent, FileChangeType, FileChange, FileOperation, FileOperationEvent } from '../../common/files';
import { FileOperationError, FileOperationResult, FileChangesEvent, FileChangeType, FileChange } from '../../common/files';
import { MessageService } from '@theia/core/lib/common/message-service';
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
import { FileSystemUtils } from '../../common';
Expand All @@ -45,7 +45,6 @@ export class FileTreeModel extends CompressedTreeModel implements LocationServic
protected override init(): void {
super.init();
this.toDispose.push(this.fileService.onDidFilesChange(changes => this.onFilesChanged(changes)));
this.toDispose.push(this.fileService.onDidRunOperation(event => this.onDidMove(event)));
}

get location(): URI | undefined {
Expand Down Expand Up @@ -92,23 +91,6 @@ export class FileTreeModel extends CompressedTreeModel implements LocationServic
}
}

/**
* to workaround https://github.com/Axosoft/nsfw/issues/42
*/
protected onDidMove(event: FileOperationEvent): void {
if (!event.isOperation(FileOperation.MOVE)) {
return;
}
if (event.resource.parent.toString() === event.target.resource.parent.toString()) {
// file rename
return;
}
this.refreshAffectedNodes([
event.resource,
event.target.resource
]);
}

protected onFilesChanged(changes: FileChangesEvent): void {
if (!this.refreshAffectedNodes(this.getAffectedUris(changes)) && this.isRootAffected(changes)) {
this.refresh();
Expand Down
54 changes: 27 additions & 27 deletions packages/filesystem/src/node/filesystem-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import { ContainerModule, interfaces } from '@theia/core/shared/inversify';
import { ConnectionHandler, RpcConnectionHandler, ILogger } from '@theia/core/lib/common';
import { FileSystemWatcherServer, FileSystemWatcherService } from '../common/filesystem-watcher-protocol';
import { FileSystemWatcherServerClient } from './filesystem-watcher-client';
import { NsfwFileSystemWatcherService, NsfwFileSystemWatcherServerOptions } from './nsfw-watcher/nsfw-filesystem-service';
import { ParcelFileSystemWatcherService, ParcelFileSystemWatcherServerOptions } from './parcel-watcher/parcel-filesystem-service';
import { NodeFileUploadService } from './node-file-upload-service';
import { NsfwOptions } from './nsfw-watcher/nsfw-options';
import { ParcelWatcherOptions } from './parcel-watcher/parcel-options';
import { DiskFileSystemProvider } from './disk-file-system-provider';
import {
remoteFileSystemPath, RemoteFileSystemServer, RemoteFileSystemClient, FileSystemProviderServer, RemoteFileSystemProxyFactory
Expand All @@ -32,16 +32,16 @@ import { BackendApplicationContribution, IPCConnectionProvider } from '@theia/co
import { RpcProxyFactory, ConnectionErrorHandler } from '@theia/core';
import { FileSystemWatcherServiceDispatcher } from './filesystem-watcher-dispatcher';

export const NSFW_SINGLE_THREADED = process.argv.includes('--no-cluster');
export const NSFW_WATCHER_VERBOSE = process.argv.includes('--nsfw-watcher-verbose');
export const WATCHER_SINGLE_THREADED = process.argv.includes('--no-cluster');
export const WATCHER_VERBOSE = process.argv.includes('--watcher-verbose');

export const NsfwFileSystemWatcherServiceProcessOptions = Symbol('NsfwFileSystemWatcherServiceProcessOptions');
export const FileSystemWatcherServiceProcessOptions = Symbol('FileSystemWatcherServiceProcessOptions');
/**
* Options to control the way the `NsfwFileSystemWatcherService` process is spawned.
* Options to control the way the `ParcelFileSystemWatcherService` process is spawned.
*/
export interface NsfwFileSystemWatcherServiceProcessOptions {
export interface FileSystemWatcherServiceProcessOptions {
/**
* Path to the script that will run the `NsfwFileSystemWatcherService` in a new process.
* Path to the script that will run the `ParcelFileSystemWatcherService` in a new process.
*/
entryPoint: string;
}
Expand All @@ -66,41 +66,41 @@ export default new ContainerModule(bind => {
});

export function bindFileSystemWatcherServer(bind: interfaces.Bind): void {
bind<NsfwOptions>(NsfwOptions).toConstantValue({});
bind<ParcelWatcherOptions>(ParcelWatcherOptions).toConstantValue({});

bind(FileSystemWatcherServiceDispatcher).toSelf().inSingletonScope();

bind(FileSystemWatcherServerClient).toSelf();
bind(FileSystemWatcherServer).toService(FileSystemWatcherServerClient);

bind<NsfwFileSystemWatcherServiceProcessOptions>(NsfwFileSystemWatcherServiceProcessOptions).toDynamicValue(ctx => ({
entryPoint: path.join(__dirname, 'nsfw-watcher'),
bind<FileSystemWatcherServiceProcessOptions>(FileSystemWatcherServiceProcessOptions).toDynamicValue(ctx => ({
entryPoint: path.join(__dirname, 'parcel-watcher'),
})).inSingletonScope();
bind<NsfwFileSystemWatcherServerOptions>(NsfwFileSystemWatcherServerOptions).toDynamicValue(ctx => {
bind<ParcelFileSystemWatcherServerOptions>(ParcelFileSystemWatcherServerOptions).toDynamicValue(ctx => {
const logger = ctx.container.get<ILogger>(ILogger);
const nsfwOptions = ctx.container.get<NsfwOptions>(NsfwOptions);
const watcherOptions = ctx.container.get<ParcelWatcherOptions>(ParcelWatcherOptions);
return {
nsfwOptions,
verbose: NSFW_WATCHER_VERBOSE,
parcelOptions: watcherOptions,
verbose: WATCHER_VERBOSE,
info: (message, ...args) => logger.info(message, ...args),
error: (message, ...args) => logger.error(message, ...args),
};
}).inSingletonScope();

bind<FileSystemWatcherService>(FileSystemWatcherService).toDynamicValue(
ctx => NSFW_SINGLE_THREADED
? createNsfwFileSystemWatcherService(ctx)
: spawnNsfwFileSystemWatcherServiceProcess(ctx)
ctx => WATCHER_SINGLE_THREADED
? createParcelFileSystemWatcherService(ctx)
: spawnParcelFileSystemWatcherServiceProcess(ctx)
).inSingletonScope();
}

/**
* Run the watch server in the current process.
*/
export function createNsfwFileSystemWatcherService(ctx: interfaces.Context): FileSystemWatcherService {
const options = ctx.container.get<NsfwFileSystemWatcherServerOptions>(NsfwFileSystemWatcherServerOptions);
export function createParcelFileSystemWatcherService(ctx: interfaces.Context): FileSystemWatcherService {
const options = ctx.container.get<ParcelFileSystemWatcherServerOptions>(ParcelFileSystemWatcherServerOptions);
const dispatcher = ctx.container.get<FileSystemWatcherServiceDispatcher>(FileSystemWatcherServiceDispatcher);
const server = new NsfwFileSystemWatcherService(options);
const server = new ParcelFileSystemWatcherService(options);
server.setClient(dispatcher);
return server;
}
Expand All @@ -109,21 +109,21 @@ export function createNsfwFileSystemWatcherService(ctx: interfaces.Context): Fil
* Run the watch server in a child process.
* Return a proxy forwarding calls to the child process.
*/
export function spawnNsfwFileSystemWatcherServiceProcess(ctx: interfaces.Context): FileSystemWatcherService {
const options = ctx.container.get<NsfwFileSystemWatcherServiceProcessOptions>(NsfwFileSystemWatcherServiceProcessOptions);
export function spawnParcelFileSystemWatcherServiceProcess(ctx: interfaces.Context): FileSystemWatcherService {
const options = ctx.container.get<FileSystemWatcherServiceProcessOptions>(FileSystemWatcherServiceProcessOptions);
const dispatcher = ctx.container.get<FileSystemWatcherServiceDispatcher>(FileSystemWatcherServiceDispatcher);
const serverName = 'nsfw-watcher';
const serverName = 'parcel-watcher';
const logger = ctx.container.get<ILogger>(ILogger);
const nsfwOptions = ctx.container.get<NsfwOptions>(NsfwOptions);
const watcherOptions = ctx.container.get<ParcelWatcherOptions>(ParcelWatcherOptions);
const ipcConnectionProvider = ctx.container.get<IPCConnectionProvider>(IPCConnectionProvider);
const proxyFactory = new RpcProxyFactory<FileSystemWatcherService>();
const serverProxy = proxyFactory.createProxy();
// We need to call `.setClient` before listening, else the JSON-RPC calls won't go through.
serverProxy.setClient(dispatcher);
const args: string[] = [
`--nsfwOptions=${JSON.stringify(nsfwOptions)}`
`--watchOptions=${JSON.stringify(watcherOptions)}`
];
if (NSFW_WATCHER_VERBOSE) {
if (WATCHER_VERBOSE) {
args.push('--verbose');
}
ipcConnectionProvider.listen({
Expand Down
Loading