diff --git a/packages/fx-core/src/component/coordinator/index.ts b/packages/fx-core/src/component/coordinator/index.ts index cb0a6e184d..d06f9be66d 100644 --- a/packages/fx-core/src/component/coordinator/index.ts +++ b/packages/fx-core/src/component/coordinator/index.ts @@ -24,6 +24,7 @@ import * as path from "path"; import * as uuid from "uuid"; import * as xml2js from "xml2js"; import { AppStudioScopes, getResourceGroupInPortal } from "../../common/constants"; +import { FeatureFlags, featureFlagManager } from "../../common/featureFlags"; import { ErrorContextMW, globalVars } from "../../common/globalVars"; import { getLocalizedString } from "../../common/localizeUtils"; import { convertToAlphanumericOnly } from "../../common/stringUtils"; @@ -54,6 +55,7 @@ import { developerPortalScaffoldUtils } from "../developerPortalScaffoldUtils"; import { DriverContext } from "../driver/interface/commonArgs"; import { updateTeamsAppV3ForPublish } from "../driver/teamsApp/appStudio"; import { Constants } from "../driver/teamsApp/constants"; +import { manifestUtils } from "../driver/teamsApp/utils/ManifestUtils"; import { Generator } from "../generator/generator"; import { Generators } from "../generator/generatorProvider"; import { ActionContext, ActionExecutionMW } from "../middleware/actionExecutionMW"; @@ -64,7 +66,6 @@ import { metadataUtil } from "../utils/metadataUtil"; import { pathUtils } from "../utils/pathUtils"; import { settingsUtil } from "../utils/settingsUtil"; import { SummaryReporter } from "./summary"; -import { featureFlagManager, FeatureFlags } from "../../common/featureFlags"; const M365Actions = [ "botAadApp/create", @@ -215,6 +216,10 @@ class Coordinator { return err(res.error); } } + + const trimRes = await manifestUtils.trimManifestShortName(projectPath); + if (trimRes.isErr()) return err(trimRes.error); + return ok({ projectPath: projectPath, warnings }); } diff --git a/packages/fx-core/src/component/driver/teamsApp/utils/ManifestUtils.ts b/packages/fx-core/src/component/driver/teamsApp/utils/ManifestUtils.ts index f8c1bb3970..3e2e6c4a40 100644 --- a/packages/fx-core/src/component/driver/teamsApp/utils/ManifestUtils.ts +++ b/packages/fx-core/src/component/driver/teamsApp/utils/ManifestUtils.ts @@ -2,7 +2,6 @@ // Licensed under the MIT license. import { hooks } from "@feathersjs/hooks"; import { - Context, FxError, IComposeExtension, IMessagingExtensionCommand, @@ -21,35 +20,34 @@ import "reflect-metadata"; import stripBom from "strip-bom"; import { v4 } from "uuid"; import isUUID from "validator/lib/isUUID"; -import { getCapabilities as checkManifestCapabilities } from "../../../../common/projectTypeChecker"; import { ErrorContextMW } from "../../../../common/globalVars"; +import { getCapabilities as checkManifestCapabilities } from "../../../../common/projectTypeChecker"; import { FileNotFoundError, JSONSyntaxError, ReadFileError } from "../../../../error/common"; import { CapabilityOptions } from "../../../../question/constants"; import { BotScenario } from "../../../constants"; import { convertManifestTemplateToV2, convertManifestTemplateToV3 } from "../../../migrate"; import { expandEnvironmentVariable } from "../../../utils/common"; -import { WrapDriverContext } from "../../util/wrapUtil"; +import { ManifestType } from "../../../utils/envFunctionUtils"; +import { DriverContext } from "../../interface/commonArgs"; import { - getBotsTplExistingAppBasedOnVersion, - getBotsTplForCommandAndResponseBasedOnVersion, - getBotsTplForNotificationBasedOnVersion, - getBotsTplBasedOnVersion, COMPOSE_EXTENSIONS_TPL_EXISTING_APP, COMPOSE_EXTENSIONS_TPL_M365_V3, COMPOSE_EXTENSIONS_TPL_V3, - getConfigurableTabsTplExistingAppBasedOnVersion, - getConfigurableTabsTplBasedOnVersion, Constants, STATIC_TABS_MAX_ITEMS, STATIC_TABS_TPL_EXISTING_APP, STATIC_TABS_TPL_V3, WEB_APPLICATION_INFO_V3, + getBotsTplBasedOnVersion, + getBotsTplExistingAppBasedOnVersion, + getBotsTplForCommandAndResponseBasedOnVersion, + getBotsTplForNotificationBasedOnVersion, + getConfigurableTabsTplBasedOnVersion, + getConfigurableTabsTplExistingAppBasedOnVersion, } from "../constants"; import { AppStudioError } from "../errors"; import { AppStudioResultFactory } from "../results"; import { getResolvedManifest } from "./utils"; -import { ManifestType } from "../../../utils/envFunctionUtils"; -import { DriverContext } from "../../interface/commonArgs"; export class ManifestUtils { async readAppManifest(projectPath: string): Promise> { @@ -393,6 +391,32 @@ export class ManifestUtils { const manifest = JSON.parse(manifestString) as TeamsAppManifest; return ok(manifest); } + + /** + * trim the short name in manifest to make sure it is no more than 25 length + */ + async trimManifestShortName( + projectPath: string, + maxLength = 25 + ): Promise> { + const manifestPath = this.getTeamsAppManifestPath(projectPath); + const manifest = (await fs.readJson(manifestPath)) as TeamsAppManifest; + const shortName = manifest.name.short; + let hasSuffix = false; + let trimmedName = shortName; + if (shortName.includes("${{APP_NAME_SUFFIX}}")) { + hasSuffix = true; + trimmedName = shortName.replace("${{APP_NAME_SUFFIX}}", ""); + } + if (trimmedName.length <= maxLength) return ok(undefined); + let newShortName = trimmedName.replace(/\s/g, "").slice(0, maxLength); + if (hasSuffix) { + newShortName += "${{APP_NAME_SUFFIX}}"; + } + manifest.name.short = newShortName; + await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2)); + return ok(undefined); + } } export const manifestUtils = new ManifestUtils(); diff --git a/packages/fx-core/tests/component/coordinator/coordinator.create.test.ts b/packages/fx-core/tests/component/coordinator/coordinator.create.test.ts index a422adb8c3..96472fca49 100644 --- a/packages/fx-core/tests/component/coordinator/coordinator.create.test.ts +++ b/packages/fx-core/tests/component/coordinator/coordinator.create.test.ts @@ -34,6 +34,7 @@ import { MockTools, randomAppName } from "../../core/utils"; import { MockedUserInteraction } from "../../plugins/solution/util"; import mockedEnv, { RestoreFn } from "mocked-env"; import { FeatureFlagName } from "../../../src/common/featureFlags"; +import { manifestUtils } from "../../../src/component/driver/teamsApp/utils/ManifestUtils"; describe("coordinator create", () => { const sandbox = sinon.createSandbox(); @@ -43,6 +44,7 @@ describe("coordinator create", () => { let mockedEnvRestore: RestoreFn; beforeEach(() => { sandbox.stub(fs, "ensureDir").resolves(); + sandbox.stub(manifestUtils, "trimManifestShortName").resolves(ok(undefined)); generator = sandbox .stub(DefaultTemplateGenerator.prototype, "scaffolding") .resolves(ok(undefined)); diff --git a/packages/fx-core/tests/component/driver/teamsApp/manifestUtils.test.ts b/packages/fx-core/tests/component/driver/teamsApp/manifestUtils.test.ts index a20dbe66f6..95c5fb4293 100644 --- a/packages/fx-core/tests/component/driver/teamsApp/manifestUtils.test.ts +++ b/packages/fx-core/tests/component/driver/teamsApp/manifestUtils.test.ts @@ -348,3 +348,39 @@ describe("readAppManifestSync", () => { assert.isTrue(res.isErr() && res.error instanceof ReadFileError); }); }); + +describe("trimManifestShortName", () => { + const sandbox = sinon.createSandbox(); + + afterEach(() => { + sandbox.restore(); + }); + + it("Success", async () => { + const teamsManifest = new TeamsAppManifest(); + teamsManifest.name.short = "shortname abcdefghijklmn123456${{APP_NAME_SUFFIX}}"; + sandbox.stub(fs, "readJson").resolves(teamsManifest); + sandbox.stub(fs, "writeFile").resolves(); + const res = await manifestUtils.trimManifestShortName("projectPath"); + assert.isTrue(res.isOk()); + assert.equal(teamsManifest.name.short, "shortnameabcdefghijklmn12${{APP_NAME_SUFFIX}}"); + }); + it("Success no suffix", async () => { + const teamsManifest = new TeamsAppManifest(); + teamsManifest.name.short = "shortname abcdefghijklmn123456"; + sandbox.stub(fs, "readJson").resolves(teamsManifest); + sandbox.stub(fs, "writeFile").resolves(); + const res = await manifestUtils.trimManifestShortName("projectPath"); + assert.isTrue(res.isOk()); + assert.equal(teamsManifest.name.short, "shortnameabcdefghijklmn12"); + }); + it("No need to trim", async () => { + const teamsManifest = new TeamsAppManifest(); + teamsManifest.name.short = "shortname abcdefghijklmn${{APP_NAME_SUFFIX}}"; + sandbox.stub(fs, "readJson").resolves(teamsManifest); + sandbox.stub(fs, "writeFile").resolves(); + const res = await manifestUtils.trimManifestShortName("projectPath"); + assert.isTrue(res.isOk()); + assert.equal(teamsManifest.name.short, "shortname abcdefghijklmn${{APP_NAME_SUFFIX}}"); + }); +});