mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-06-16 17:16:34 +00:00
fix: workaround for # in the app path
Closes #1815 Ref eclipse-theia/theia#12064 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
parent
ca687cfe40
commit
a15a94a339
@ -113,6 +113,11 @@ import { MessagingContribution } from './theia/core/messaging-contribution';
|
||||
import { MessagingService } from '@theia/core/lib/node/messaging/messaging-service';
|
||||
import { HostedPluginReader } from './theia/plugin-ext/plugin-reader';
|
||||
import { HostedPluginReader as TheiaHostedPluginReader } from '@theia/plugin-ext/lib/hosted/node/plugin-reader';
|
||||
import { PluginDeployer } from '@theia/plugin-ext/lib/common/plugin-protocol';
|
||||
import {
|
||||
LocalDirectoryPluginDeployerResolverWithFallback,
|
||||
PluginDeployer_GH_12064,
|
||||
} from './theia/plugin-ext/plugin-deployer';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(BackendApplication).toSelf().inSingletonScope();
|
||||
@ -392,6 +397,12 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
// https://github.com/arduino/arduino-ide/pull/1706#pullrequestreview-1195595080
|
||||
bind(HostedPluginReader).toSelf().inSingletonScope();
|
||||
rebind(TheiaHostedPluginReader).toService(HostedPluginReader);
|
||||
|
||||
// https://github.com/eclipse-theia/theia/issues/12064
|
||||
bind(LocalDirectoryPluginDeployerResolverWithFallback)
|
||||
.toSelf()
|
||||
.inSingletonScope();
|
||||
rebind(PluginDeployer).to(PluginDeployer_GH_12064).inSingletonScope();
|
||||
});
|
||||
|
||||
function bindChildLogger(bind: interfaces.Bind, name: string): void {
|
||||
|
@ -0,0 +1,100 @@
|
||||
import { URI } from '@theia/core/lib/common/uri';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import {
|
||||
PluginDeployerResolver,
|
||||
PluginDeployerResolverContext,
|
||||
} from '@theia/plugin-ext/lib/common/plugin-protocol';
|
||||
import { PluginDeployerImpl } from '@theia/plugin-ext/lib/main/node/plugin-deployer-impl';
|
||||
import { LocalDirectoryPluginDeployerResolver } from '@theia/plugin-ext/lib/main/node/resolvers/local-directory-plugin-deployer-resolver';
|
||||
import { constants, promises as fs } from 'fs';
|
||||
import { isAbsolute, resolve } from 'path';
|
||||
|
||||
@injectable()
|
||||
export class LocalDirectoryPluginDeployerResolverWithFallback extends LocalDirectoryPluginDeployerResolver {
|
||||
override async resolve(
|
||||
pluginResolverContext: PluginDeployerResolverContext
|
||||
): Promise<void> {
|
||||
const origin = pluginResolverContext.getOriginId();
|
||||
// The original implementation must not run when there is a hash in the path. Otherwise, it can resolve an undesired directory.
|
||||
// Consider app under c:\Users\username\Desktop\# here is my app\
|
||||
// Then the flawed logic will incorrectly find c:\Users\username\Desktop location after stripping the rest of the path after the hash.
|
||||
// The implementation which provides a workaround for the hash in the path assumes that the original Theia logic is correct, when no hash present in the URI path.
|
||||
let localPath: string | null;
|
||||
if (origin.includes('#')) {
|
||||
localPath = await resolveLocalPluginPathFallback(
|
||||
pluginResolverContext,
|
||||
this.supportedScheme
|
||||
);
|
||||
} else {
|
||||
localPath = await this.originalResolveLocalPluginPath(
|
||||
pluginResolverContext,
|
||||
this.supportedScheme
|
||||
);
|
||||
}
|
||||
if (localPath) {
|
||||
await this.resolveFromLocalPath(pluginResolverContext, localPath);
|
||||
}
|
||||
}
|
||||
|
||||
private async originalResolveLocalPluginPath(
|
||||
context: PluginDeployerResolverContext,
|
||||
scheme: string
|
||||
): Promise<string | null> {
|
||||
const object = <Record<string, unknown>>this;
|
||||
if (
|
||||
'resolveLocalPluginPath' in object &&
|
||||
typeof object['resolveLocalPluginPath'] === 'function'
|
||||
) {
|
||||
return object['resolveLocalPluginPath'](context, scheme);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveLocalPluginPathFallback(
|
||||
context: PluginDeployerResolverContext,
|
||||
scheme: string
|
||||
): Promise<string | null> {
|
||||
const uri = new URI(context.getOriginId());
|
||||
if (uri.scheme === scheme) {
|
||||
const unencodedRawUri = uri.toString(true);
|
||||
let fsPath = unencodedRawUri.substring(`${scheme}:`.length);
|
||||
if (!isAbsolute(fsPath)) {
|
||||
fsPath = resolve(process.cwd(), fsPath);
|
||||
}
|
||||
try {
|
||||
await fs.access(fsPath, constants.R_OK);
|
||||
return fsPath;
|
||||
} catch {
|
||||
console.warn(
|
||||
`The local plugin referenced by ${context.getOriginId()} does not exist.`
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class PluginDeployer_GH_12064 extends PluginDeployerImpl {
|
||||
@inject(LocalDirectoryPluginDeployerResolverWithFallback)
|
||||
private readonly pluginResolver: LocalDirectoryPluginDeployerResolverWithFallback;
|
||||
|
||||
@postConstruct()
|
||||
protected adjustPluginResolvers(): void {
|
||||
const pluginResolvers = <PluginDeployerResolver[]>(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(this as any).pluginResolvers
|
||||
);
|
||||
const index = pluginResolvers.findIndex(
|
||||
(pluginResolver) =>
|
||||
pluginResolver instanceof LocalDirectoryPluginDeployerResolver
|
||||
);
|
||||
if (index >= 0) {
|
||||
pluginResolvers.splice(index, 1, this.pluginResolver);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user