Skip to content

Commit 2a875b0

Browse files
authored
Merge pull request #225 from OfficeDev/implement-manifest-choice
Put both types of manifest in the same branch
2 parents ebfb53b + 09a6e40 commit 2a875b0

File tree

7 files changed

+311
-78
lines changed

7 files changed

+311
-78
lines changed

.vscode/tasks.json

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
{
2-
// See https://go.microsoft.com/fwlink/?LinkId=733558
3-
// for the documentation about the tasks.json format
42
"version": "2.0.0",
53
"tasks": [
64
{
@@ -34,7 +32,7 @@
3432
"script": "start:desktop -- --app excel",
3533
"presentation": {
3634
"clear": true,
37-
"panel": "dedicated",
35+
"panel": "dedicated"
3836
},
3937
"problemMatcher": []
4038
},
@@ -44,7 +42,7 @@
4442
"script": "start:desktop -- --app outlook",
4543
"presentation": {
4644
"clear": true,
47-
"panel": "dedicated",
45+
"panel": "dedicated"
4846
},
4947
"problemMatcher": []
5048
},
@@ -54,7 +52,7 @@
5452
"script": "start:desktop -- --app powerpoint",
5553
"presentation": {
5654
"clear": true,
57-
"panel": "dedicated",
55+
"panel": "dedicated"
5856
},
5957
"problemMatcher": []
6058
},
@@ -64,7 +62,7 @@
6462
"script": "start:desktop -- --app word",
6563
"presentation": {
6664
"clear": true,
67-
"panel": "dedicated",
65+
"panel": "dedicated"
6866
},
6967
"problemMatcher": []
7068
},
@@ -125,6 +123,6 @@
125123
"panel": "dedicated"
126124
},
127125
"problemMatcher": []
128-
},
126+
}
129127
]
130128
}

assets/color.png

1.04 KB
Loading

assets/outline.png

249 Bytes
Loading

convertToSingleHost.js

Lines changed: 156 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
/* global require, process, console */
22

3-
const convertTest = process.argv[3] === "convert-test";
43
const fs = require("fs");
5-
const host = process.argv[2];
6-
const hosts = ["excel", "onenote", "outlook", "powerpoint", "project", "word"];
74
const path = require("path");
85
const util = require("util");
6+
const manifest = require("office-addin-manifest");
7+
8+
const host = process.argv[2];
9+
const manifestType = process.argv[3];
10+
const projectName = process.argv[4];
11+
let appId = process.argv[5];
12+
const hosts = ["excel", "onenote", "outlook", "powerpoint", "project", "word"];
913
const testPackages = [
1014
"@types/mocha",
1115
"@types/node",
12-
"current-processes",
1316
"mocha",
1417
"office-addin-mock",
1518
"office-addin-test-helpers",
@@ -29,112 +32,79 @@ async function modifyProjectForSingleHost(host) {
2932
}
3033
await convertProjectToSingleHost(host);
3134
await updatePackageJsonForSingleHost(host);
32-
if (!convertTest) {
33-
await updateLaunchJsonFile();
34-
}
35+
await updateLaunchJsonFile();
3536
}
3637

3738
async function convertProjectToSingleHost(host) {
38-
// copy host-specific manifest over manifest.xml
39+
// Copy host-specific manifest over manifest.xml
3940
const manifestContent = await readFileAsync(`./manifest.${host}.xml`, "utf8");
4041
await writeFileAsync(`./manifest.xml`, manifestContent);
4142

42-
// copy over host-specific taskpane code to taskpane.ts
43+
// Copy over host-specific taskpane code to taskpane.ts
4344
const srcContent = await readFileAsync(`./src/taskpane/${host}.ts`, "utf8");
4445
await writeFileAsync(`./src/taskpane/taskpane.ts`, srcContent);
4546

46-
// delete all test files by default for now - eventually we want to convert the tests by default
47-
if (convertTest && (host === "excel" || host === "word")) {
48-
// copy over host-specific taskpane test code to test-taskpane.ts
49-
const testTaskpaneContent = await readFileAsync(`./test/src/${host}-test-taskpane.ts`, "utf8");
50-
const updatedTestTaskpaneContent = testTaskpaneContent.replace(
51-
`../../src/taskpane/${host}`,
52-
`../../src/taskpane/taskpane`
53-
);
54-
await writeFileAsync(`./test/src/test-taskpane.ts`, updatedTestTaskpaneContent);
55-
56-
// update ui-test.ts to only run against specified host
57-
const testContent = await readFileAsync(`./test/ui-test.ts`, "utf8");
58-
const updatedTestContent = testContent.replace(`const hosts = ["Excel", "Word"]`, `const hosts = ["${host}"]`);
59-
await writeFileAsync(`./test/ui-test.ts`, updatedTestContent);
60-
61-
// delete all host-specific test files after converting to single host
62-
hosts.forEach(async function (host) {
63-
if (host == "excel" || host == "word") {
64-
await unlinkFileAsync(`./test/src/${host}-test-taskpane.ts`);
65-
}
66-
});
67-
} else {
68-
deleteFolder(path.resolve(`./test`));
69-
}
70-
71-
// delete all host-specific files
47+
// Delete all host-specific files
7248
hosts.forEach(async function (host) {
7349
await unlinkFileAsync(`./manifest.${host}.xml`);
7450
await unlinkFileAsync(`./src/taskpane/${host}.ts`);
7551
});
7652

77-
// delete the .github folder
53+
// Delete test folder
54+
deleteFolder(path.resolve(`./test`));
55+
56+
// Delete the .github folder
7857
deleteFolder(path.resolve(`./.github`));
7958

80-
// delete CI/CD pipeline files
59+
// Delete CI/CD pipeline files
8160
deleteFolder(path.resolve(`./.azure-devops`));
8261

83-
// delete repo support files
62+
// Delete repo support files
8463
await deleteSupportFiles();
8564
}
8665

8766
async function updatePackageJsonForSingleHost(host) {
88-
// update package.json to reflect selected host
67+
// Update package.json to reflect selected host
8968
const packageJson = `./package.json`;
9069
const data = await readFileAsync(packageJson, "utf8");
9170
let content = JSON.parse(data);
92-
93-
// update 'config' section in package.json to use selected host
71+
72+
// Update 'config' section in package.json to use selected host
9473
content.config["app_to_debug"] = host;
9574

96-
// remove 'engines' section
75+
// Remove 'engines' section
9776
delete content.engines;
9877

99-
// update sideload and unload scripts to use selected host.
100-
["sideload", "unload"].forEach((key) => {
101-
content.scripts[key] = content.scripts[`${key}:${host}`];
102-
});
103-
104-
// remove scripts that are unrelated to the selected host
78+
// Remove scripts that are unrelated to the selected host
10579
Object.keys(content.scripts).forEach(function (key) {
10680
if (
107-
key.startsWith("sideload:") ||
108-
key.startsWith("unload:") ||
10981
key === "convert-to-single-host" ||
11082
key === "start:desktop:outlook"
11183
) {
11284
delete content.scripts[key];
11385
}
11486
});
11587

116-
if (!convertTest) {
117-
// remove test-related scripts
118-
Object.keys(content.scripts).forEach(function (key) {
119-
if (key.includes("test")) {
120-
delete content.scripts[key];
121-
}
122-
});
123-
124-
// remove test-related packages
125-
Object.keys(content.devDependencies).forEach(function (key) {
126-
if (testPackages.includes(key)) {
127-
delete content.devDependencies[key];
128-
}
129-
});
130-
}
88+
// Remove test-related scripts
89+
Object.keys(content.scripts).forEach(function (key) {
90+
if (key.includes("test")) {
91+
delete content.scripts[key];
92+
}
93+
});
13194

132-
// write updated json to file
95+
// Remove test-related packages
96+
Object.keys(content.devDependencies).forEach(function (key) {
97+
if (testPackages.includes(key)) {
98+
delete content.devDependencies[key];
99+
}
100+
});
101+
102+
// Write updated JSON to file
133103
await writeFileAsync(packageJson, JSON.stringify(content, null, 2));
134104
}
135105

136106
async function updateLaunchJsonFile() {
137-
// remove 'Debug Tests' configuration from launch.json
107+
// Remove 'Debug Tests' configuration from launch.json
138108
const launchJson = `.vscode/launch.json`;
139109
const launchJsonContent = await readFileAsync(launchJson, "utf8");
140110
const regex = /(.+{\r?\n.*"name": "Debug (?:UI|Unit) Tests",\r?\n(?:.*\r?\n)*?.*},.*\r?\n)/gm;
@@ -171,11 +141,129 @@ async function deleteSupportFiles() {
171141
await unlinkFileAsync("package-lock.json");
172142
}
173143

144+
async function deleteJSONManifestRelatedFiles() {
145+
await unlinkFileAsync("manifest.json");
146+
await unlinkFileAsync("assets/color.png");
147+
await unlinkFileAsync("assets/outline.png");
148+
}
149+
150+
async function deleteXMLManifestRelatedFiles() {
151+
await unlinkFileAsync("webpack.config.js");
152+
await unlinkFileAsync("manifest.xml");
153+
}
154+
155+
async function updatePackageJsonForXMLManifest() {
156+
const packageJson = `./package.json`;
157+
const data = await readFileAsync(packageJson, "utf8");
158+
let content = JSON.parse(data);
159+
160+
// Remove scripts that are only used with JSON manifest
161+
delete content.scripts["signin"];
162+
delete content.scripts["signout"];
163+
164+
// Write updated JSON to file
165+
await writeFileAsync(packageJson, JSON.stringify(content, null, 2));
166+
}
167+
168+
async function updatePackageJsonForJSONManifest() {
169+
const packageJson = `./package.json`;
170+
const data = await readFileAsync(packageJson, "utf8");
171+
let content = JSON.parse(data);
172+
173+
// Remove special start scripts
174+
Object.keys(content.scripts).forEach(function (key) {
175+
if (key.includes("start:")) {
176+
delete content.scripts[key];
177+
}
178+
});
179+
180+
// Change manifest file name extension
181+
content.scripts.start = "office-addin-debugging start manifest.json";
182+
content.scripts.stop = "office-addin-debugging stop manifest.json";
183+
content.scripts.validate = "office-addin-manifest validate manifest.json";
184+
185+
// Write updated JSON to file
186+
await writeFileAsync(packageJson, JSON.stringify(content, null, 2));
187+
}
188+
189+
async function updateTasksJsonFileForJSONManifest() {
190+
const tasksJson = `.vscode/tasks.json`;
191+
const data = await readFileAsync(tasksJson, "utf8");
192+
let content = JSON.parse(data);
193+
194+
content.tasks.forEach(function (task) {
195+
if (task.label.startsWith("Build")) {
196+
task.dependsOn = [ "Install" ];
197+
};
198+
if (task.label === "Debug: Outlook Desktop") {
199+
task.script = "start";
200+
task.dependsOn = [ "Check OS", "Install" ];
201+
}
202+
});
203+
204+
const checkOSTask = {
205+
label: "Check OS",
206+
type: "shell",
207+
windows: {
208+
command: "echo 'Sideloading in Outlook on Windows is supported'"
209+
},
210+
linux: {
211+
command: "echo 'Sideloading on Linux is not supported' && exit 1"
212+
},
213+
osx: {
214+
command: "echo 'Sideloading in Outlook on Mac is not supported' && exit 1"
215+
},
216+
presentation: {
217+
clear: true,
218+
panel: "dedicated"
219+
}
220+
};
221+
222+
content.tasks.push(checkOSTask);
223+
await writeFileAsync(tasksJson, JSON.stringify(content, null, 2));
224+
}
225+
226+
async function updateWebpackConfigForJSONManifest() {
227+
const webPack = `webpack.config.js`;
228+
const webPackContent = await readFileAsync(webPack, "utf8");
229+
const updatedContent = webPackContent.replace(".xml", ".json");
230+
await writeFileAsync(webPack, updatedContent);
231+
}
232+
233+
async function modifyProjectForJSONManifest() {
234+
await updatePackageJsonForJSONManifest();
235+
await updateWebpackConfigForJSONManifest();
236+
await updateTasksJsonFileForJSONManifest();
237+
await deleteXMLManifestRelatedFiles();
238+
}
239+
174240
/**
175241
* Modify the project so that it only supports a single host.
176242
* @param host The host to support.
177243
*/
178244
modifyProjectForSingleHost(host).catch((err) => {
179-
console.error(`Error: ${err instanceof Error ? err.message : err}`);
245+
console.error(`Error modifying for single host: ${err instanceof Error ? err.message : err}`);
180246
process.exitCode = 1;
181247
});
248+
249+
let manifestPath = "manifest.xml";
250+
251+
if ((host !== "outlook") || (manifestType !== "json")) {
252+
// Remove things that are only relevant to JSON manifest
253+
deleteJSONManifestRelatedFiles();
254+
updatePackageJsonForXMLManifest();
255+
} else {
256+
manifestPath = "manifest.json";
257+
modifyProjectForJSONManifest().catch((err) => {
258+
console.error(`Error modifying for JSON manifest: ${err instanceof Error ? err.message : err}`);
259+
process.exitCode = 1;
260+
});
261+
};
262+
263+
if (projectName) {
264+
if (!appId) {
265+
appId = "random";
266+
}
267+
manifest.OfficeAddinManifest.modifyManifestFile(manifestPath, appId, projectName);
268+
}
269+

0 commit comments

Comments
 (0)