Skip to content

Commit 0a77832

Browse files
authored
Merge pull request MicrosoftDocs#1961 from Fogolan/tools
MILESTONE 1, 2, 3
2 parents 4bc562b + dac86c8 commit 0a77832

File tree

10 files changed

+333
-250
lines changed

10 files changed

+333
-250
lines changed

tools/office-cmdlet-updater/config/default.json

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
{
22
"platyPS": {
3+
"credentials": {
4+
"login": "",
5+
"pass": ""
6+
},
37
"docs": [
48
{
59
"name": "teams",
@@ -10,10 +14,31 @@
1014
"name": "skype",
1115
"path": "..\\..\\skype\\skype-ps\\skype",
1216
"metaTags": ["Skype for Business Online"]
17+
},
18+
{
19+
"name": "sharepoint",
20+
"path": "..\\..\\sharepoint\\sharepoint-ps\\sharepoint-online",
21+
"metaTags": []
22+
},
23+
{
24+
"name": "staffhub",
25+
"path": "..\\..\\staffhub\\staffhub-ps\\staffhub",
26+
"metaTags": []
27+
},
28+
{
29+
"name": "whiteboard",
30+
"path": "..\\..\\whiteboard\\whiteboard-ps\\whiteboard",
31+
"metaTags": []
32+
},
33+
{
34+
"name": "exchange",
35+
"path": "..\\..\\exchange\\exchange-ps\\exchange",
36+
"metaTags": []
1337
}
1438
],
1539
"ignoreFiles": [
16-
"..\\..\\teams\\teams-ps\\teams\\teams.md"
40+
"..\\..\\teams\\teams-ps\\teams\\teams.md",
41+
"..\\..\\whiteboard\\whiteboard-ps\\whiteboard\\whiteboard.md"
1742
]
1843
},
1944
"sendgrid": {
Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
module.exports = {
22
GET_TEAM: 'Get-Team',
3-
INSTALL_MICROSOFT_TEAM: 'Install-Module MicrosoftTeams -SkipPublisherCheck',
3+
INSTALL_MICROSOFT_TEAM: 'Install-Module MicrosoftTeams -SkipPublisherCheck -Force',
44
CONNECT_MICROSOFT_TEAM: 'Connect-MicrosoftTeams',
5-
INSTALL_PLATYPS: 'Install-Module -Name platyPS -SkipPublisherCheck -Scope CurrentUser',
5+
INSTALL_PLATYPS: 'Install-Module -Name platyPS -SkipPublisherCheck -Scope CurrentUser -Force',
66
IMPORT_PLATYPS: 'Import-Module platyPS',
7-
UPDATE_MARKDOWN: 'Update-MarkdownHelp -Path "{}" -LogPath "{}"',
7+
UPDATE_MARKDOWN: 'Update-MarkdownHelp -Path "{}" -LogPath "{}" -Session $Session',
88
SKYPE_SET_POLICY: 'Set-ExecutionPolicy RemoteSigned ',
99
SKYPE_INSTALL_MODULE: 'Import-Module "C:\\\\Program Files\\\\Common Files\\\\Skype for Business Online\\\\Modules\\\\SkypeOnlineConnector\\\\SkypeOnlineConnector.psd1" -Force',
1010
SKYPE_GET_CRED: '$cred = Get-Credential',
1111
SKYPE_CREATE_SESSION: '$session = New-CsOnlineSession -Credential $cred -Verbose',
12-
SKYPE_IMPORT_SESSION: 'Import-PSSession -Session $session'
12+
SKYPE_IMPORT_SESSION: 'Import-PSSession -Session $session',
13+
SHAREPOINT_INSTALL_MODULE: 'Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking',
14+
WHITEBOARD_INSTALL_MODULE: 'Install-Module -Name WhiteboardAdmin',
15+
EXCHANGE_INSTALL_MODULE: 'Install-Module -Name ExchangeOnlineShell -Force',
16+
EXCHANGE_GET_CRED: '$UserCredential = Get-Credential',
17+
EXCHANGE_GET_SESSION: '$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $cred -Authentication Basic -AllowRedirection',
18+
EXCHANGE_SESSION_IMPORT: 'Import-PSSession $Session -DisableNameChecking',
19+
SET_LOGIN: '$Username = \'{}\'',
20+
SET_PASS: '$Password = \'{}\'',
21+
CONVERT_PASS_TO_SEC_STRING: '$SecureString = ConvertTo-SecureString -AsPlainText $Password -Force',
22+
CREAT_CRED: '$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username,$SecureString',
23+
STUFFHUB_INSTALL: 'Install-Module -Name MicrosoftStaffHub -RequiredVersion 1.0.0-alpha -AllowPrerelease'
1324
};

tools/office-cmdlet-updater/controllers/markdown.controller.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@ class MarkdownController {
1313
let err;
1414
const { docs } = this.config.get('platyPS');
1515

16-
[, err] = await of(this.powerShellService.preInstall());
17-
18-
if (err) {
19-
throw new Error(err);
20-
}
21-
2216
docs.forEach(async (doc) => {
2317
if (!(await fs.pathExists(doc.path))) {
2418
throw new Error(powerShellErrors.DOC_PATH_DOESNT_EXIST);

tools/office-cmdlet-updater/helpers/di.container.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const LogParseService = require('../services/log.parse.service');
77
const MailNotificationService = require('../services/mail.notification.service');
88
const MarkdownController = require('../controllers/markdown.controller');
99
const db = require('../db')();
10+
const CmdletDependenciesService = require('../services/cmdlet.dependencies.service');
11+
const FsService = require('../services/fs.service');
1012

1113
module.exports = () => {
1214
const container = awilix.createContainer({
@@ -26,8 +28,12 @@ module.exports = () => {
2628
logStoreService: awilix.asClass(LogStoreService).singleton(),
2729
logParseService: awilix.asClass(LogParseService).singleton(),
2830
powerShellService: awilix.asClass(PowerShellService).singleton(),
29-
markdownService: awilix.asClass(MarkdownService).singleton()
30-
});
31+
cmdletDependenciesService: awilix
32+
.asClass(CmdletDependenciesService)
33+
.singleton(),
34+
fsService: awilix.asClass(FsService).singleton(),
35+
markdownService: awilix.asClass(MarkdownService).singleton()
36+
});
3137

3238
container.register({
3339
markdownController: awilix.asClass(MarkdownController).singleton()
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
const commands = require('../constants/commands');
2+
const format = require('string-format');
3+
4+
class CmdletDependenciesService {
5+
constructor(powerShellService, config) {
6+
this.ps = powerShellService;
7+
this.config = config;
8+
}
9+
10+
async installDependencies({ cmdletName }) {
11+
await this.installPlatyPs();
12+
13+
switch (cmdletName) {
14+
case 'teams': {
15+
await this.preInstallTeams();
16+
break;
17+
}
18+
case 'skype': {
19+
const { login, pass } = this._getCredentialsFromConfig();
20+
21+
await this.preInstallSkype({ login, pass });
22+
break;
23+
}
24+
case 'sharepoint': {
25+
await this.preInstallSharepoint();
26+
break;
27+
}
28+
case 'whiteboard': {
29+
await this.preInstallWhiteboard();
30+
break;
31+
}
32+
case 'exchange': {
33+
const { login, pass } = this._getCredentialsFromConfig();
34+
35+
await this.preInstallExchange({ login, pass });
36+
break;
37+
}
38+
case 'staffhub': {
39+
await this.preInstallStuffHub();
40+
break;
41+
}
42+
}
43+
}
44+
45+
async installPlatyPs() {
46+
await this.ps.invokeCommand(commands.INSTALL_PLATYPS);
47+
await this.ps.invokeCommand(commands.IMPORT_PLATYPS);
48+
}
49+
50+
async preInstallTeams() {
51+
// TODO: check if user already auth
52+
53+
await this.ps.invokeCommand(commands.INSTALL_MICROSOFT_TEAM);
54+
await this.ps.invokeCommand(commands.CONNECT_MICROSOFT_TEAM);
55+
}
56+
57+
async preInstallSharepoint() {
58+
await this.ps.invokeCommand(commands.SHAREPOINT_INSTALL_MODULE);
59+
}
60+
61+
async preInstallSkype({ login, pass }) {
62+
await this._createCredInPs({ login, pass });
63+
64+
// await this.ps.invokeCommand(commands.SKYPE_INSTALL_MODULE);
65+
await this.ps.invokeCommand(commands.SKYPE_CREATE_SESSION);
66+
await this.ps.invokeCommand(commands.SKYPE_IMPORT_SESSION);
67+
68+
return result;
69+
}
70+
71+
async preInstallWhiteboard() {
72+
await this.ps.invokeCommand(commands.WHITEBOARD_INSTALL_MODULE);
73+
}
74+
75+
async preInstallExchange({ login, pass }) {
76+
await this._createCredInPs({ login, pass });
77+
78+
//await this.ps.invokeCommand(commands.EXCHANGE_INSTALL_MODULE);
79+
await this.ps.invokeCommand(commands.EXCHANGE_GET_SESSION);
80+
await this.ps.invokeCommand(commands.EXCHANGE_SESSION_IMPORT);
81+
}
82+
83+
async preInstallStuffHub() {
84+
// TODO: install module when installation error will be fix
85+
// await this.ps.invokeCommand(commands.STUFFHUB_INSTALL);
86+
}
87+
88+
_getCredentialsFromConfig() {
89+
const { login, pass } = this.config.get('platyPS.credentials');
90+
91+
if (!login || !pass) {
92+
throw new Error('Invalid credentials');
93+
}
94+
95+
return { login, pass };
96+
}
97+
98+
async _createCredInPs({ login, pass }) {
99+
await this.ps.invokeCommand(format(commands.SET_LOGIN, login));
100+
await this.ps.invokeCommand(format(commands.SET_PASS, pass));
101+
102+
await this.ps.invokeCommand(commands.CONVERT_PASS_TO_SEC_STRING);
103+
await this.ps.invokeCommand(commands.CREAT_CRED);
104+
}
105+
}
106+
107+
module.exports = CmdletDependenciesService;
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
const path = require('path');
2+
const fs = require('fs-extra');
3+
const shortId = require('shortid');
4+
5+
class FsService {
6+
constructor(config, logStoreService) {
7+
this.config = config;
8+
this.logStoreService = logStoreService;
9+
10+
this.getTempFolderPath = this.getTempFolderPath.bind(this);
11+
this.removeTempFolders = this.removeTempFolders.bind(this);
12+
}
13+
14+
// region getModuleFiles
15+
16+
async getModuleFiles({ path, metaTags }) {
17+
const { ignoreFiles } = this.config.get('platyPS');
18+
19+
const mdFiles = await this._getMdFiles(path);
20+
21+
return mdFiles.filter(
22+
(fileName) =>
23+
!this._isFileIgnore({ fileName, ignoreFiles }) &&
24+
this._isContainsTag({ filePath: fileName, metaTags })
25+
);
26+
}
27+
28+
async _getMdFiles(folderPath) {
29+
const mdExt = '.md';
30+
31+
const allFiles = await this._getFolderFiles(folderPath);
32+
33+
return allFiles.filter((file) => file.endsWith(mdExt));
34+
}
35+
36+
async _getFolderFiles(folderPath) {
37+
const files = await fs.readdir(folderPath);
38+
39+
return await files.reduce(async (promiseResult, filePath) => {
40+
const result = await promiseResult;
41+
const absolute = path.resolve(folderPath, filePath);
42+
43+
const fileStat = await fs.stat(absolute);
44+
45+
if (fileStat.isDirectory()) {
46+
const subDirFiles = await this._getFolderFiles(absolute);
47+
48+
return [...result, ...subDirFiles];
49+
}
50+
51+
return [...result, absolute];
52+
}, []);
53+
}
54+
55+
_isFileIgnore({ fileName, ignoreFiles }) {
56+
const ignoreAbsolutePathsArr = ignoreFiles.map((f) => path.resolve(f));
57+
58+
const absoluteFilePath = path.resolve(fileName);
59+
60+
return ignoreAbsolutePathsArr.includes(absoluteFilePath);
61+
}
62+
63+
_isContainsTag({ filePath, metaTags }) {
64+
if (!metaTags.length) {
65+
return true;
66+
}
67+
68+
const metaTagRegex = /(?<=applicable: ).+/gmu;
69+
70+
const groups = fs
71+
.readFileSync(filePath, 'utf8')
72+
.toString()
73+
.match(metaTagRegex);
74+
75+
if (!groups) {
76+
return false;
77+
}
78+
79+
for (const metaTag of metaTags) {
80+
if (groups[0].indexOf(metaTag) !== -1) {
81+
return true;
82+
}
83+
}
84+
85+
return false;
86+
}
87+
88+
// endregion
89+
90+
getTempFolderPath({ name, path }) {
91+
let tempFolders = this.logStoreService.getAllTempFolders();
92+
93+
if (!tempFolders.has(name)) {
94+
const tempFolderPath = `${path}\\${shortId()}`;
95+
96+
this.logStoreService.addTempFolder(tempFolderPath, name);
97+
98+
tempFolders = this.logStoreService.getAllTempFolders();
99+
}
100+
101+
return tempFolders.get(name);
102+
}
103+
104+
async copyMdInTempFolder(srcFilePath, tempFolderPath) {
105+
const fileName = path.basename(srcFilePath);
106+
const distFilePath = `${tempFolderPath}\\${fileName}`;
107+
108+
await fs.ensureDir(tempFolderPath);
109+
110+
await fs.copy(srcFilePath, distFilePath);
111+
112+
return distFilePath;
113+
}
114+
115+
async getFileContent(logFilePath) {
116+
await fs.ensureFile(logFilePath);
117+
118+
return (await fs.readFile(logFilePath)).toString();
119+
}
120+
121+
async removeTempFolders() {
122+
const { getAllTempFolders } = this.logStoreService;
123+
124+
const tempFolders = [...getAllTempFolders().values()];
125+
126+
const tempFoldersPath = tempFolders.map((path) => path[0]);
127+
128+
for (const path of tempFoldersPath) {
129+
if (fs.pathExists(path)) {
130+
fs.remove(path);
131+
}
132+
}
133+
}
134+
}
135+
136+
module.exports = FsService;

tools/office-cmdlet-updater/services/log.parse.service.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@ class LogParseService {
3939
}
4040

4141
parseAll() {
42-
const parseLogs = []
43-
const logs = [...this.logStoreService.getAllLogs().values()].reduce(
42+
const parseLogs = [];
43+
44+
const allLogs = [...this.logStoreService.getAllLogs().values()];
45+
46+
const logs = allLogs.reduce(
4447
(acc, cur) => [...acc, ...cur],
4548
[]
4649
);

tools/office-cmdlet-updater/services/log.store.service.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const moment = require('moment');
55
class LogStoreService {
66
constructor(db) {
77
this.db = db;
8+
9+
this.getAllTempFolders = this.getAllTempFolders.bind(this);
810
}
911

1012
addLog(log, name) {

0 commit comments

Comments
 (0)