Skip to content
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
72 changes: 71 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,77 @@
- [Previous Changelogs](https://github.com/opensumi/core/releases)
- [Previous Breaking Changes](https://github.com/opensumi/core/wiki/Breaking-Changes)

## [Pre-release] v2.23.0
## v2.23.0

### What's New Features

- feat: support electron titlebar string template by @yantze in https://github.com/opensumi/core/pull/2194
- feat: add empty implementation for `Terminal Location` API by @bytemain in https://github.com/opensumi/core/pull/2202
- feat: add cli engine by @bk1012 in https://github.com/opensumi/core/pull/2210
- chore: show extension download error by @bk1012 in https://github.com/opensumi/core/pull/2266
- feat: menubar component will reset focus after click by @pipiiiiii in https://github.com/opensumi/core/pull/2284
- feat: read-only resource render lock icon by @Ricbet in https://github.com/opensumi/core/pull/2309
- feat: support inspectExtensionHost config by @Ricbet in https://github.com/opensumi/core/pull/2310
- feat: breadcrumbs support menus by @wangxiaojuan in https://github.com/opensumi/core/pull/2258
- feat: editor tab title display file path by @hacke2 in https://github.com/opensumi/core/pull/2343
- feat: statusbar pophover support icon by @hacke2 in https://github.com/opensumi/core/pull/2340
- feat: compatibility with the experimental API registerTimelineProvider by @PerfectPan in https://github.com/opensumi/core/pull/2438
- feat: toolbar dropdown-button contribute by @hacke2 in https://github.com/opensumi/core/pull/2312

### Refactor

- refactor: remove some useless icons by @erha19 in https://github.com/opensumi/core/pull/2204
- refactor: remove unused application error definition by @erha19 in https://github.com/opensumi/core/pull/2403
- fix: ensure outline is displayed properly by @bytemain in https://github.com/opensumi/core/pull/2440

### Style Changes

- style: improve outline treenode style by @erha19 in https://github.com/opensumi/core/pull/2329

### Other Changes

- fix: collaboration initialize by @Ricbet in https://github.com/opensumi/core/pull/2207
- build(deps): bump cookiejar from 2.1.3 to 2.1.4 by @dependabot in https://github.com/opensumi/core/pull/2216
- fix: remove collaboration preference code by @Ricbet in https://github.com/opensumi/core/pull/2221
- build(deps): bump http-cache-semantics from 4.1.0 to 4.1.1 in /tools/electron by @dependabot in https://github.com/opensumi/core/pull/2236
- chore: add E2E test badge by @erha19 in https://github.com/opensumi/core/pull/2237
- fix: quick open hightlight label whitespace by @Ricbet in https://github.com/opensumi/core/pull/2265
- fix: support Trim Final NewLines configuration by @pipiiiiii in https://github.com/opensumi/core/pull/2277
- chore: remove engines required on package.json by @erha19 in https://github.com/opensumi/core/pull/2267
- fix: scm badge is too large to display the problem by @wangxiaojuan in https://github.com/opensumi/core/pull/2274
- chore: update license notice by @erha19 in https://github.com/opensumi/core/pull/2300
- fix: add margins to the QuickOpen input by @wangxiaojuan in https://github.com/opensumi/core/pull/2299
- fix: modified readonly logic of diff editor by @Ricbet in https://github.com/opensumi/core/pull/2295
- chore: update extension engine version to 1.68.0 by @erha19 in https://github.com/opensumi/core/pull/2302
- chore: improve terminal debug test by @erha19 in https://github.com/opensumi/core/pull/2304
- tests: add collaboration module test case by @pipiiiiii in https://github.com/opensumi/core/pull/2306
- fix: support normal prelunchTask on debug by @erha19 in https://github.com/opensumi/core/pull/2330
- fix: sync file dirty status after spliting files by @erha19 in https://github.com/opensumi/core/pull/2323
- chore: remove drivelist by @AhkunTa in https://github.com/opensumi/core/pull/2281
- fix(collaboration): change default color by @winjo in https://github.com/opensumi/core/pull/2348
- chore: remove useless application interface by @erha19 in https://github.com/opensumi/core/pull/2344
- fix: improve context menu content fontsize by @wangxiaojuan in https://github.com/opensumi/core/pull/2351
- chore: update render mode comment by @erha19 in https://github.com/opensumi/core/pull/2353
- Revert "fix: use bash resolve shellpath" by @yantze in https://github.com/opensumi/core/pull/2347
- chore: remove unused value in extension.service.ts by @bk1012 in https://github.com/opensumi/core/pull/2375
- ci: add workflow for code review by @bytemain in https://github.com/opensumi/core/pull/2395
- test: scm list view mode e2e by @Ricbet in https://github.com/opensumi/core/pull/2387
- fix: show theme quick picker after theme extension installed by @PerfectPan in https://github.com/opensumi/core/pull/2398
- chore: remove node-notifier from cli-engine by @erha19 in https://github.com/opensumi/core/pull/2400
- fix: remove status bar warnings by @erha19 in https://github.com/opensumi/core/pull/2407
- chore: update community information by @erha19 in https://github.com/opensumi/core/pull/2413
- chore: build cli-engine before publish by @erha19 in https://github.com/opensumi/core/pull/2430
- chore: download extension on Windows by @fankangsong in https://github.com/opensumi/core/pull/2436
- chore: update cli-engine versison by @erha19 in https://github.com/opensumi/core/pull/2422
- ci: add secrets check by @erha19 in https://github.com/opensumi/core/pull/2439
- chore: support build cli-engine before release by @erha19 in https://github.com/opensumi/core/pull/2441
- fix: namespace conflicts between extHost and extBrowser by @yantze in https://github.com/opensumi/core/pull/2415
- fix: support haxe hashlink debug by @erha19 in https://github.com/opensumi/core/pull/2393
- fix: logger should have default value to avoid error to be overridden by @miserylee in https://github.com/opensumi/core/pull/2433
- fix: output clear icon lag renderer by @Ricbet in https://github.com/opensumi/core/pull/2447
- fix: file watcher path error on Windows by @erha19 in https://github.com/opensumi/core/pull/2455
- fix: electron menus will be called more than once by @erha19 in https://github.com/opensumi/core/pull/2453
- fix: ensure preference ready before render editor by @bytemain in https://github.com/opensumi/core/pull/2451

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

Expand Down
2 changes: 1 addition & 1 deletion packages/core-common/src/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export type ILocalizationKey = string; // ts不支持symbol作为key

let _currentLanguageId = 'zh-CN';

const localizationRegistryMap = new CaseInsensitiveMap<string, LocalizationRegistry>();
export const localizationRegistryMap = new CaseInsensitiveMap<string, LocalizationRegistry>();

export function localize(
symbol: ILocalizationKey,
Expand Down
122 changes: 71 additions & 51 deletions packages/file-service/__tests__/node/file-service-watcher.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,29 @@ import { FileSystemWatcherServer } from '../../src/node/file-service-watcher';
function sleep(time: number) {
return new Promise((resolve) => setTimeout(resolve, time));
}

jest.setTimeout(10000);

let seed = 1;
const sleepTime = 1000;

(isMacintosh ? describe.skip : describe)('ParceWatcher Test', () => {
const track = temp.track();
const sleepTime = 1000;
let injector: MockInjector;
let root: URI;
let watcherServer: FileSystemWatcherServer;
let watcherId: number;

beforeEach(async () => {
injector = createNodeInjector([]);
root = FileUri.create(fse.realpathSync(await temp.mkdir('parce-watcher-test')));
const watcherServerList: FileSystemWatcherServer[] = [];
let seed = 1;

async function generateWatcher() {
const injector = createNodeInjector([]);
const root = FileUri.create(fse.realpathSync(await temp.mkdir(`parce-watcher-test-${seed++}`)));
// @ts-ignore
injector.mock(FileSystemWatcherServer, 'isEnableNSFW', () => false);
watcherServer = injector.get(FileSystemWatcherServer);
watcherId = await watcherServer.watchFileChanges(root.toString());
});
const watcherServer = injector.get(FileSystemWatcherServer);
const watcherId = await watcherServer.watchFileChanges(root.toString());

return { root, watcherServer, watcherId };
}

afterEach(async () => {
afterAll(async () => {
track.cleanupSync();
watcherServer.dispose();
watcherServerList.forEach((watcherServer) => {
watcherServer.dispose();
});
});

it('Should receive file changes events from in the workspace by default.', async () => {
Expand All @@ -47,6 +45,8 @@ let seed = 1;
event.changes.forEach((c) => actualUris.add(c.uri.toString()));
},
};

const { root, watcherServer } = await generateWatcher();
watcherServer.setClient(watcherClient);

const expectedUris = [
Expand All @@ -55,10 +55,10 @@ let seed = 1;
root.withPath(root.path.join('foo', 'bar', 'baz.txt')).toString(),
];

await fse.mkdir(FileUri.fsPath(root.resolve('foo')));
await fse.mkdir(FileUri.fsPath(root.resolve('foo')), { recursive: true });
expect(fse.statSync(FileUri.fsPath(root.resolve('foo'))).isDirectory()).toBe(true);

await fse.mkdir(FileUri.fsPath(root.resolve('foo').resolve('bar')));
await fse.mkdir(FileUri.fsPath(root.resolve('foo').resolve('bar')), { recursive: true });
expect(fse.statSync(FileUri.fsPath(root.resolve('foo').resolve('bar'))).isDirectory()).toBe(true);

await fse.writeFile(FileUri.fsPath(root.resolve('foo').resolve('bar').resolve('baz.txt')), 'baz');
Expand All @@ -67,6 +67,8 @@ let seed = 1;
);
await sleep(sleepTime);
expect(expectedUris).toEqual(Array.from(actualUris));

watcherServerList.push(watcherServer);
});

it('Should not receive file changes events from in the workspace by default if unwatched', async () => {
Expand All @@ -77,16 +79,17 @@ let seed = 1;
event.changes.forEach((c) => actualUris.add(c.uri.toString()));
},
};
const { root, watcherServer, watcherId } = await generateWatcher();
watcherServer.setClient(watcherClient);

/* Unwatch root */
await watcherServer.unwatchFileChanges(watcherId);

fse.mkdirSync(FileUri.fsPath(root.resolve('foo')));
fse.mkdirSync(FileUri.fsPath(root.resolve('foo')), { recursive: true });
expect(fse.statSync(FileUri.fsPath(root.resolve('foo'))).isDirectory()).toBe(true);
await sleep(sleepTime);

fse.mkdirSync(FileUri.fsPath(root.resolve('foo').resolve('bar')));
fse.mkdirSync(FileUri.fsPath(root.resolve('foo').resolve('bar')), { recursive: true });
expect(fse.statSync(FileUri.fsPath(root.resolve('foo').resolve('bar'))).isDirectory()).toBe(true);
await sleep(sleepTime);

Expand All @@ -95,79 +98,91 @@ let seed = 1;
'baz',
);
await sleep(sleepTime);

expect(actualUris.size).toEqual(0);

watcherServerList.push(watcherServer);
});

it('Merge common events on one watcher', async () => {
const folderName = `folder_${seed++}`;
const { root, watcherServer, watcherId } = await generateWatcher();
const folderName = `folder_${seed}`;
const newFolder = FileUri.fsPath(root.resolve(folderName));
expect(watcherId).toBeDefined();
fse.mkdirSync(newFolder);
fse.mkdirSync(newFolder, { recursive: true });
const newWatcherId = await watcherServer.watchFileChanges(newFolder);
expect(newWatcherId === watcherId).toBeTruthy();
watcherServerList.push(watcherServer);
});

it('Can receive events while watch file is not existed', async () => {
const folderName = `folder_${seed++}`;
const { root, watcherServer, watcherId } = await generateWatcher();

const folderName = `folder_${seed}`;
const newFolder = FileUri.fsPath(root.resolve(folderName));
expect(watcherId).toBeDefined();
fse.mkdirSync(newFolder);
fse.mkdirSync(newFolder, { recursive: true });
const parentId = await watcherServer.watchFileChanges(newFolder);
const childFile = FileUri.fsPath(root.resolve(folderName).resolve('index.js'));
const childId = await watcherServer.watchFileChanges(childFile);
expect(parentId === childId).toBeTruthy();
watcherServerList.push(watcherServer);
});

it('Excludes options should be worked', async () => {
const watcherClient = {
onDidFilesChanged: jest.fn(),
};
const { root, watcherServer } = await generateWatcher();
watcherServer.setClient(watcherClient);
const folderName = `folder_${seed++}`;

const folderName = `folder_${seed}`;
const newFolder = FileUri.fsPath(root.resolve(folderName));
const fileA = FileUri.fsPath(root.resolve(folderName).resolve('a'));
const fileB = FileUri.fsPath(root.resolve(folderName).resolve('b'));
fse.mkdirSync(newFolder);

fse.mkdirSync(newFolder, { recursive: true });
await sleep(sleepTime);
watcherClient.onDidFilesChanged.mockClear();

let id = await watcherServer.watchFileChanges(newFolder, { excludes: [] });
await fse.ensureFile(fileA);
await sleep(sleepTime);
expect(watcherClient.onDidFilesChanged).toBeCalledTimes(1);
await watcherServer.unwatchFileChanges(id);

id = await watcherServer.watchFileChanges(newFolder, { excludes: ['**/b/**'] });
await fse.ensureFile(fileB);
await sleep(sleepTime);
expect(watcherClient.onDidFilesChanged).toBeCalledTimes(1);
watcherServer.unwatchFileChanges(id);
await watcherServer.unwatchFileChanges(id);
watcherServerList.push(watcherServer);
});
});

(isMacintosh ? describe.skip : describe)('Watch file rename/move/new', () => {
jest.setTimeout(10000);

const track = temp.track();
const sleepTime = 1000;
let root: URI;
let watcherServer: FileSystemWatcherServer;
let injector: MockInjector;

beforeEach(async () => {
injector = createNodeInjector([]);
root = FileUri.create(fse.realpathSync(temp.mkdirSync('nsfw-test')));
fse.mkdirpSync(FileUri.fsPath(root.resolve('for_rename_folder')));
fse.writeFileSync(FileUri.fsPath(root.resolve('for_rename')), 'rename');

async function generateWatcher() {
const injector = createNodeInjector([]);
const root = FileUri.create(fse.realpathSync(await temp.mkdir('nfsw-test')));
// @ts-ignore
injector.mock(FileSystemWatcherServer, 'isEnableNSFW', () => false);
watcherServer = injector.get(FileSystemWatcherServer);
const watcherServer = injector.get(FileSystemWatcherServer);

fse.mkdirpSync(FileUri.fsPath(root.resolve('for_rename_folder')));
fse.writeFileSync(FileUri.fsPath(root.resolve('for_rename')), 'rename');

await watcherServer.watchFileChanges(root.toString());
await sleep(sleepTime);
});

afterEach(() => {
return { root, watcherServer };
}
const watcherServerList: FileSystemWatcherServer[] = [];

afterAll(async () => {
track.cleanupSync();
watcherServer.dispose();
watcherServerList.forEach((watcherServer) => {
watcherServer.dispose();
});
});

it('Rename file', async () => {
Expand All @@ -186,7 +201,7 @@ let seed = 1;
});
},
};

const { root, watcherServer } = await generateWatcher();
watcherServer.setClient(watcherClient);

const expectedAddUris = [root.resolve('for_rename_renamed').toString()];
Expand All @@ -198,6 +213,7 @@ let seed = 1;

expect([...addUris]).toEqual(expectedAddUris);
expect([...deleteUris]).toEqual(expectedDeleteUris);
watcherServerList.push(watcherServer);
});

it('Move file', async () => {
Expand All @@ -217,11 +233,12 @@ let seed = 1;
},
};

const { root, watcherServer } = await generateWatcher();
watcherServer.setClient(watcherClient);

const expectedAddUris = [root.resolve('for_rename_folder').resolve('for_rename').toString()];

const expectedDeleteUris = [root.resolve('for_rename').toString()];

await fse.move(
FileUri.fsPath(root.resolve('for_rename')),
FileUri.fsPath(root.resolve('for_rename_folder').resolve('for_rename')),
Expand All @@ -234,6 +251,7 @@ let seed = 1;

expect(Array.from(addUris)).toEqual(expectedAddUris);
expect(Array.from(deleteUris)).toEqual(expectedDeleteUris);
watcherServerList.push(watcherServer);
});

it('Move file on current directry', async () => {
Expand All @@ -252,7 +270,7 @@ let seed = 1;
});
},
};

const { root, watcherServer } = await generateWatcher();
watcherServer.setClient(watcherClient);

const expectedAddUris = [root.resolve('for_rename_1').toString()];
Expand All @@ -266,6 +284,7 @@ let seed = 1;

expect(Array.from(addUris)).toEqual(expectedAddUris);
expect(Array.from(deleteUris)).toEqual(expectedDeleteUris);
watcherServerList.push(watcherServer);
});

it('New file', async () => {
Expand All @@ -284,7 +303,7 @@ let seed = 1;
});
},
};

const { root, watcherServer } = await generateWatcher();
watcherServer.setClient(watcherClient);

const expectedAddUris = [root.resolve('README.md').toString()];
Expand All @@ -296,5 +315,6 @@ let seed = 1;

expect(Array.from(addUris)).toEqual(expectedAddUris);
expect(Array.from(deleteUris)).toEqual(expectedDeleteUris);
watcherServerList.push(watcherServer);
});
});