Skip to content

Commit

Permalink
fix: support relative path to runtime (#5950)
Browse files Browse the repository at this point in the history
* Properly support relative path to runtime

* refactor path computation into a single method on the botproject model

Co-authored-by: Andy Brown <asbrown002@gmail.com>
  • Loading branch information
benbrown and a-b-r-o-w-n authored Feb 26, 2021
1 parent 5930547 commit ae1ccdc
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 69 deletions.
21 changes: 11 additions & 10 deletions Composer/packages/server/src/models/bot/botProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,23 +195,24 @@ export class BotProject implements IBotProject {
};
};

/**
* return the absolute path to the runtime project for use when starting or building the app
*/
public getRuntimePath = (): string | undefined => {
let runtimePath = this.settings?.runtime?.path;
if (runtimePath && !Path.isAbsolute(runtimePath)) {
runtimePath = Path.resolve(this.dir, 'settings', runtimePath);
}
return runtimePath;
};

public getDefaultSlotEnvSettings = async (obfuscate: boolean) => {
return await this.settingManager.get(obfuscate);
};

public getEnvSettings = async (obfuscate: boolean) => {
const settings = await this.settingManager.get(obfuscate);

// Resolve relative path for custom runtime if the path is relative
if (settings?.runtime?.customRuntime && settings.runtime.path && !Path.isAbsolute(settings.runtime.path)) {
const absolutePath = Path.resolve(this.dir, 'settings', settings.runtime.path);

if (fs.existsSync(absolutePath)) {
settings.runtime.path = absolutePath;
await this.updateEnvSettings(settings);
}
}

// fix old bot have no language settings
if (!settings?.defaultLanguage) {
settings.defaultLanguage = defaultLanguage;
Expand Down
47 changes: 25 additions & 22 deletions Composer/packages/server/src/utility/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,31 +62,34 @@ export async function getNewProjRef(
export async function ejectAndMerge(currentProject: BotProject, jobId: string) {
if (currentProject.settings?.runtime?.customRuntime === true) {
const runtime = ExtensionContext.getRuntimeByProject(currentProject);
const runtimePath = currentProject.settings.runtime.path;
const runtimePath = currentProject.getRuntimePath();
if (runtimePath) {
if (!fs.existsSync(runtimePath)) {
await runtime.eject(currentProject, currentProject.fileStorage);
}

if (!fs.existsSync(runtimePath)) {
await runtime.eject(currentProject, currentProject.fileStorage);
}

// install all dependencies and build the app
BackgroundProcessManager.updateProcess(jobId, 202, formatMessage('Building runtime'));
await runtime.build(runtimePath, currentProject);
// install all dependencies and build the app
BackgroundProcessManager.updateProcess(jobId, 202, formatMessage('Building runtime'));
await runtime.build(runtimePath, currentProject);

const manifestFile = runtime.identifyManifest(currentProject.dataDir, currentProject.name);
const manifestFile = runtime.identifyManifest(currentProject.dataDir, currentProject.name);

// run the merge command to merge all package dependencies from the template to the bot project
BackgroundProcessManager.updateProcess(jobId, 202, formatMessage('Merging Packages'));
const realMerge = new SchemaMerger(
[manifestFile, '!**/imported/**', '!**/generated/**'],
Path.join(currentProject.dataDir, 'schemas/sdk'),
Path.join(currentProject.dataDir, 'dialogs/imported'),
false,
false,
console.log,
console.warn,
console.error
);
// run the merge command to merge all package dependencies from the template to the bot project
BackgroundProcessManager.updateProcess(jobId, 202, formatMessage('Merging Packages'));
const realMerge = new SchemaMerger(
[manifestFile, '!**/imported/**', '!**/generated/**'],
Path.join(currentProject.dataDir, 'schemas/sdk'),
Path.join(currentProject.dataDir, 'dialogs/imported'),
false,
false,
console.log,
console.warn,
console.error
);

await realMerge.merge();
await realMerge.merge();
} else {
log('Schema merge step skipped for project without runtime path');
}
}
}
8 changes: 2 additions & 6 deletions extensions/azurePublish/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,17 +330,13 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
let runtimeCodePath = runtime.path;

// If the project is using an "ejected" runtime, use that version of the code instead of the built-in template
// TODO: this templatePath should come from the runtime instead of this magic parameter
if (
project.settings &&
project.settings.runtime &&
project.settings.runtime.customRuntime === true &&
project.settings.runtime.path
) {
runtimeCodePath = path.isAbsolute(project.settings.runtime.path)
? project.settings.runtime.path
: path.resolve(project.dir, project.settings.runtime.path);
}
)
runtimeCodePath = project.getRuntimePath(); // get computed absolute path

// Prepare the temporary project
// this writes all the settings to the root settings/appsettings.json file
Expand Down
9 changes: 2 additions & 7 deletions extensions/localPublish/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,7 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
'azurewebapp'
);
} else if (project.settings.runtime.path && project.settings.runtime.command) {
const runtimePath = path.isAbsolute(project.settings.runtime.path)
? project.settings.runtime.path
: path.resolve(project.dataDir, project.settings.runtime.path);
const runtimePath = project.getRuntimePath();
await runtime.build(runtimePath, project);
await runtime.setSkillManifest(
project.settings.runtime.path,
Expand Down Expand Up @@ -343,10 +341,7 @@ class LocalPublisher implements PublishPlugin<PublishConfig> {
};

private startBot = async (botId: string, port: number, settings: any, project: any): Promise<string> => {
let customRuntimePath = settings.runtime.path;
if (customRuntimePath && !path.isAbsolute(customRuntimePath)) {
customRuntimePath = path.resolve(project.dir, customRuntimePath);
}
const customRuntimePath = project.getRuntimePath();
const botDir = settings.runtime?.customRuntime === true ? customRuntimePath : this.getBotRuntimeDir(botId);

const commandAndArgs =
Expand Down
42 changes: 18 additions & 24 deletions extensions/packageManager/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

import * as path from 'path';
import * as fs from 'fs';
import { readdirSync, readFileSync } from 'fs';

import * as semverSort from 'semver-sort';
import axios from 'axios';
import { IExtensionRegistration } from '@botframework-composer/types';
import { SchemaMerger } from '@microsoft/bf-dialog/lib/library/schemaMerger';
import { readdirSync, readFileSync } from 'fs';
import { parseStringPromise } from 'xml2js';

const API_ROOT = '/api';
Expand Down Expand Up @@ -268,11 +269,9 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
} catch (err) {
composer.log('Could not load library from URL');
composer.log(err);
return res
.status(err.response?.status || 500)
.json({
message: `Could not load feed. Please check the feed URL and format. Error message: ${err.message}`,
});
return res.status(err.response?.status || 500).json({
message: `Could not load feed. Please check the feed URL and format. Error message: ${err.message}`,
});
}
}

Expand All @@ -295,10 +294,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
mergeErrors.push(msg);
};

let runtimePath = currentProject.settings?.runtime?.path;
if (runtimePath && !path.isAbsolute(runtimePath)) {
runtimePath = path.resolve(currentProject.dir, runtimePath);
}
const runtimePath = currentProject.getRuntimePath();

if (currentProject.settings?.runtime?.customRuntime && runtimePath) {
const manifestFile = runtime.identifyManifest(runtimePath, currentProject.name);
Expand Down Expand Up @@ -350,10 +346,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
mergeErrors.push(msg);
};

let runtimePath = currentProject.settings?.runtime?.path;
if (runtimePath && !path.isAbsolute(runtimePath)) {
runtimePath = path.resolve(currentProject.dir, runtimePath);
}
const runtimePath = currentProject.getRuntimePath();

if (packageName && runtimePath) {
try {
Expand Down Expand Up @@ -422,12 +415,15 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
}

// update the settings.plugins array
const newlyInstalledPlugin = installedComponents.find(c=>c.includesSchema && c.name==packageName);
if (newlyInstalledPlugin && !currentProject.settings.runtimeSettings?.plugins?.find((p)=>p.name===newlyInstalledPlugin.name)) {
const newlyInstalledPlugin = installedComponents.find((c) => c.includesSchema && c.name == packageName);
if (
newlyInstalledPlugin &&
!currentProject.settings.runtimeSettings?.plugins?.find((p) => p.name === newlyInstalledPlugin.name)
) {
const newSettings = currentProject.settings;
if (!newSettings.runtimeSettings) {
newSettings.runtimeSettings = {
plugins: []
plugins: [],
};
}
newSettings.runtimeSettings.plugins.push({
Expand Down Expand Up @@ -478,10 +474,7 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
mergeErrors.push(msg);
};

let runtimePath = currentProject.settings?.runtime?.path;
if (runtimePath && !path.isAbsolute(runtimePath)) {
runtimePath = path.resolve(currentProject.dir, runtimePath);
}
const runtimePath = currentProject.getRuntimePath();

// get URL or package name
const packageName = req.body.package;
Expand Down Expand Up @@ -515,12 +508,13 @@ export default async (composer: IExtensionRegistration): Promise<void> => {
});

// update the settings.plugins array
if (currentProject.settings.runtimeSettings?.plugins?.find((p)=>p.name===packageName)) {
if (currentProject.settings.runtimeSettings?.plugins?.find((p) => p.name === packageName)) {
const newSettings = currentProject.settings;
newSettings.runtimeSettings.plugins = newSettings.runtimeSettings.plugins.filter((p)=>p.name!==packageName);
newSettings.runtimeSettings.plugins = newSettings.runtimeSettings.plugins.filter(
(p) => p.name !== packageName
);
currentProject.updateEnvSettings(newSettings);
}

} catch (err) {
res.json({
success: false,
Expand Down

0 comments on commit ae1ccdc

Please sign in to comment.