mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-20 10:19:02 +00:00
Generate macOS configuration profiles (#241773)
* generate configuration policy and manifests * add darwin pipeline job * argument for per-platform generation of policy * adopt argument in pipeline * formatting tweaks in generated profile (+ check in .js file) * tidy up output plists * copy policy definitions * implement the remaining renderProfileValue() * remove unnecessary platform option * copy to .app in vscode-darwin-$PLATFORM-min-ci gulp task * add darwinProfileUUID and darwinProfilePayloadUUID to product.json * better way to package in gulp script * bump distro commit (c3ec5ba485) * Add bundles policy paths to macOS universal build 'filesToSkip' Needs this when creating universal macOS app: Expected all non-binary files to have identical SHAs when creating a universal build but "Contents/Resources/app/policies/cs-cz/com.microsoft.VSCodeInsiders.plist" did not See:298a872f5f/src/index.ts (L163-L172)
This commit is contained in:
@@ -121,6 +121,11 @@ steps:
|
|||||||
|
|
||||||
- template: ../common/install-builtin-extensions.yml@self
|
- template: ../common/install-builtin-extensions.yml@self
|
||||||
|
|
||||||
|
- ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}:
|
||||||
|
- script: node build/lib/policies darwin
|
||||||
|
displayName: Generate policy definitions
|
||||||
|
retryCountOnTaskFailure: 3
|
||||||
|
|
||||||
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
|
- ${{ if ne(parameters.VSCODE_QUALITY, 'oss') }}:
|
||||||
- script: |
|
- script: |
|
||||||
set -e
|
set -e
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ steps:
|
|||||||
- template: ../common/install-builtin-extensions.yml@self
|
- template: ../common/install-builtin-extensions.yml@self
|
||||||
|
|
||||||
- ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}:
|
- ${{ if and(ne(parameters.VSCODE_CIBUILD, true), ne(parameters.VSCODE_QUALITY, 'oss')) }}:
|
||||||
- powershell: node build\lib\policies
|
- powershell: node build\lib\policies win32
|
||||||
displayName: Generate Group Policy definitions
|
displayName: Generate Group Policy definitions
|
||||||
retryCountOnTaskFailure: 3
|
retryCountOnTaskFailure: 3
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ async function main(buildDir) {
|
|||||||
const filesToSkip = [
|
const filesToSkip = [
|
||||||
'**/CodeResources',
|
'**/CodeResources',
|
||||||
'**/Credits.rtf',
|
'**/Credits.rtf',
|
||||||
|
'**/policies/{*.mobileconfig,**/*.plist}',
|
||||||
// TODO: Should we consider expanding this to other files in this area?
|
// TODO: Should we consider expanding this to other files in this area?
|
||||||
'**/node_modules/@parcel/node-addon-api/nothing.target.mk'
|
'**/node_modules/@parcel/node-addon-api/nothing.target.mk'
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ async function main(buildDir?: string) {
|
|||||||
const filesToSkip = [
|
const filesToSkip = [
|
||||||
'**/CodeResources',
|
'**/CodeResources',
|
||||||
'**/Credits.rtf',
|
'**/Credits.rtf',
|
||||||
|
'**/policies/{*.mobileconfig,**/*.plist}',
|
||||||
// TODO: Should we consider expanding this to other files in this area?
|
// TODO: Should we consider expanding this to other files in this area?
|
||||||
'**/node_modules/@parcel/node-addon-api/nothing.target.mk'
|
'**/node_modules/@parcel/node-addon-api/nothing.target.mk'
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -372,8 +372,9 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
|
|||||||
const shortcut = gulp.src('resources/darwin/bin/code.sh')
|
const shortcut = gulp.src('resources/darwin/bin/code.sh')
|
||||||
.pipe(replace('@@APPNAME@@', product.applicationName))
|
.pipe(replace('@@APPNAME@@', product.applicationName))
|
||||||
.pipe(rename('bin/code'));
|
.pipe(rename('bin/code'));
|
||||||
|
const policyDest = gulp.src('.build/policies/darwin/**', { base: '.build/policies/darwin' })
|
||||||
all = es.merge(all, shortcut);
|
.pipe(rename(f => f.dirname = `policies/${f.dirname}`));
|
||||||
|
all = es.merge(all, shortcut, policyDest);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = all
|
let result = all
|
||||||
|
|||||||
@@ -46,6 +46,19 @@ function renderADMLString(prefix, moduleName, nlsString, translations) {
|
|||||||
}
|
}
|
||||||
return `<string id="${prefix}_${nlsString.nlsKey.replace(/\./g, '_')}">${value}</string>`;
|
return `<string id="${prefix}_${nlsString.nlsKey.replace(/\./g, '_')}">${value}</string>`;
|
||||||
}
|
}
|
||||||
|
function renderProfileString(_prefix, moduleName, nlsString, translations) {
|
||||||
|
let value;
|
||||||
|
if (translations) {
|
||||||
|
const moduleTranslations = translations[moduleName];
|
||||||
|
if (moduleTranslations) {
|
||||||
|
value = moduleTranslations[nlsString.nlsKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!value) {
|
||||||
|
value = nlsString.value;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
class BasePolicy {
|
class BasePolicy {
|
||||||
type;
|
type;
|
||||||
name;
|
name;
|
||||||
@@ -84,6 +97,14 @@ class BasePolicy {
|
|||||||
renderADMLPresentation() {
|
renderADMLPresentation() {
|
||||||
return `<presentation id="${this.name}">${this.renderADMLPresentationContents()}</presentation>`;
|
return `<presentation id="${this.name}">${this.renderADMLPresentationContents()}</presentation>`;
|
||||||
}
|
}
|
||||||
|
renderProfile() {
|
||||||
|
return [`<key>${this.name}</key>`, this.renderProfileValue()];
|
||||||
|
}
|
||||||
|
renderProfileManifest(translations) {
|
||||||
|
return `<dict>
|
||||||
|
${this.renderProfileManifestValue(translations)}
|
||||||
|
</dict>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class BooleanPolicy extends BasePolicy {
|
class BooleanPolicy extends BasePolicy {
|
||||||
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
||||||
@@ -106,6 +127,21 @@ class BooleanPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
|
return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
|
||||||
}
|
}
|
||||||
|
renderProfileValue() {
|
||||||
|
return `<false/>`;
|
||||||
|
}
|
||||||
|
renderProfileManifestValue(translations) {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<false/>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>boolean</string>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class ParseError extends Error {
|
class ParseError extends Error {
|
||||||
constructor(message, moduleName, node) {
|
constructor(message, moduleName, node) {
|
||||||
@@ -138,6 +174,21 @@ class NumberPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
|
return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
|
||||||
}
|
}
|
||||||
|
renderProfileValue() {
|
||||||
|
return `<integer>${this.defaultValue}</integer>`;
|
||||||
|
}
|
||||||
|
renderProfileManifestValue(translations) {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<integer>${this.defaultValue}</integer>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>integer</string>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class StringPolicy extends BasePolicy {
|
class StringPolicy extends BasePolicy {
|
||||||
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
||||||
@@ -156,6 +207,21 @@ class StringPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
|
return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
|
||||||
}
|
}
|
||||||
|
renderProfileValue() {
|
||||||
|
return `<string></string>`;
|
||||||
|
}
|
||||||
|
renderProfileManifestValue(translations) {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<string></string>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class ObjectPolicy extends BasePolicy {
|
class ObjectPolicy extends BasePolicy {
|
||||||
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
static from(name, category, minimumVersion, description, moduleName, settingNode) {
|
||||||
@@ -174,6 +240,22 @@ class ObjectPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<multiTextBox refId="${this.name}" />`;
|
return `<multiTextBox refId="${this.name}" />`;
|
||||||
}
|
}
|
||||||
|
renderProfileValue() {
|
||||||
|
return `<string></string>`;
|
||||||
|
}
|
||||||
|
renderProfileManifestValue(translations) {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<string></string>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
class StringEnumPolicy extends BasePolicy {
|
class StringEnumPolicy extends BasePolicy {
|
||||||
enum_;
|
enum_;
|
||||||
@@ -220,6 +302,25 @@ class StringEnumPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<dropdownList refId="${this.name}" />`;
|
return `<dropdownList refId="${this.name}" />`;
|
||||||
}
|
}
|
||||||
|
renderProfileValue() {
|
||||||
|
return `<string>${this.enum_[0]}</string>`;
|
||||||
|
}
|
||||||
|
renderProfileManifestValue(translations) {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<string>${this.enum_[0]}</string>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
<key>pfm_range_list</key>
|
||||||
|
<array>
|
||||||
|
${this.enum_.map(e => `<string>${e}</string>`).join('\n ')}
|
||||||
|
</array>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const NumberQ = {
|
const NumberQ = {
|
||||||
Q: `(number) @value`,
|
Q: `(number) @value`,
|
||||||
@@ -425,6 +526,186 @@ function renderADML(appName, versions, categories, policies, translations) {
|
|||||||
</policyDefinitionResources>
|
</policyDefinitionResources>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
function renderProfileManifest(appName, bundleIdentifier, _versions, _categories, policies, translations) {
|
||||||
|
const requiredPayloadFields = `
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>Configure ${appName}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadDescription</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Description</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>${appName}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadDisplayName</string>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Display Name</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadIdentifier</string>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Identifier</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadType</string>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Type</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string></string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadUUID</string>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload UUID</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadVersion</string>
|
||||||
|
<key>pfm_range_list</key>
|
||||||
|
<array>
|
||||||
|
<integer>1</integer>
|
||||||
|
</array>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Version</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>integer</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>Microsoft</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadOrganization</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Organization</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>`;
|
||||||
|
const profileManifestSubkeys = policies.map(policy => {
|
||||||
|
return policy.renderProfileManifest(translations);
|
||||||
|
}).join('');
|
||||||
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>pfm_app_url</key>
|
||||||
|
<string>https://code.visualstudio.com/</string>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${appName} Managed Settings</string>
|
||||||
|
<key>pfm_documentation_url</key>
|
||||||
|
<string>https://code.visualstudio.com/docs/setup/enterprise</string>
|
||||||
|
<key>pfm_domain</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>pfm_format_version</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>pfm_interaction</key>
|
||||||
|
<string>combined</string>
|
||||||
|
<key>pfm_last_modified</key>
|
||||||
|
<date>${new Date().toISOString().replace(/\.\d+Z$/, 'Z')}</date>
|
||||||
|
<key>pfm_platforms</key>
|
||||||
|
<array>
|
||||||
|
<string>macOS</string>
|
||||||
|
</array>
|
||||||
|
<key>pfm_subkeys</key>
|
||||||
|
<array>
|
||||||
|
${requiredPayloadFields}
|
||||||
|
${profileManifestSubkeys}
|
||||||
|
</array>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${appName}</string>
|
||||||
|
<key>pfm_unique</key>
|
||||||
|
<true/>
|
||||||
|
<key>pfm_version</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>`;
|
||||||
|
}
|
||||||
|
function renderMacOSPolicy(policies, translations) {
|
||||||
|
const appName = product.nameLong;
|
||||||
|
const bundleIdentifier = product.darwinBundleIdentifier;
|
||||||
|
const payloadUUID = product.darwinProfilePayloadUUID;
|
||||||
|
const UUID = product.darwinProfileUUID;
|
||||||
|
const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort();
|
||||||
|
const categories = [...new Set(policies.map(p => p.category))];
|
||||||
|
const policyEntries = policies.map(policy => policy.renderProfile())
|
||||||
|
.flat()
|
||||||
|
.map(entry => `\t\t\t\t${entry}`)
|
||||||
|
.join('\n');
|
||||||
|
return {
|
||||||
|
profile: `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>PayloadContent</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>${appName}</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>${bundleIdentifier}.${UUID}</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>${UUID}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
${policyEntries}
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>This profile manages ${appName}. For more information see https://code.visualstudio.com/docs/setup/enterprise</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>${appName}</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>PayloadOrganization</key>
|
||||||
|
<string>Microsoft</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>${payloadUUID}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>TargetDeviceType</key>
|
||||||
|
<integer>5</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>`,
|
||||||
|
manifests: [{ languageId: 'en-us', contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies) },
|
||||||
|
...translations.map(({ languageId, languageTranslations }) => ({ languageId, contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies, languageTranslations) }))
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
function renderGP(policies, translations) {
|
function renderGP(policies, translations) {
|
||||||
const appName = product.nameLong;
|
const appName = product.nameLong;
|
||||||
const regKey = product.win32RegValueName;
|
const regKey = product.win32RegValueName;
|
||||||
@@ -540,14 +821,9 @@ async function getTranslations() {
|
|||||||
return await Promise.all(languageIds.map(languageId => getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version)
|
return await Promise.all(languageIds.map(languageId => getNLS(extensionGalleryServiceUrl, resourceUrlTemplate, languageId, version)
|
||||||
.then(languageTranslations => ({ languageId, languageTranslations }))));
|
.then(languageTranslations => ({ languageId, languageTranslations }))));
|
||||||
}
|
}
|
||||||
async function main() {
|
async function windowsMain(policies, translations) {
|
||||||
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
|
|
||||||
console.log(`Found ${policies.length} policies:`);
|
|
||||||
for (const policy of policies) {
|
|
||||||
console.log(`- ${policy.name} (${policy.type})`);
|
|
||||||
}
|
|
||||||
const { admx, adml } = await renderGP(policies, translations);
|
|
||||||
const root = '.build/policies/win32';
|
const root = '.build/policies/win32';
|
||||||
|
const { admx, adml } = await renderGP(policies, translations);
|
||||||
await fs_1.promises.rm(root, { recursive: true, force: true });
|
await fs_1.promises.rm(root, { recursive: true, force: true });
|
||||||
await fs_1.promises.mkdir(root, { recursive: true });
|
await fs_1.promises.mkdir(root, { recursive: true });
|
||||||
await fs_1.promises.writeFile(path_1.default.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n'));
|
await fs_1.promises.writeFile(path_1.default.join(root, `${product.win32RegValueName}.admx`), admx.replace(/\r?\n/g, '\n'));
|
||||||
@@ -557,6 +833,36 @@ async function main() {
|
|||||||
await fs_1.promises.writeFile(path_1.default.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n'));
|
await fs_1.promises.writeFile(path_1.default.join(languagePath, `${product.win32RegValueName}.adml`), contents.replace(/\r?\n/g, '\n'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async function darwinMain(policies, translations) {
|
||||||
|
const bundleIdentifier = product.darwinBundleIdentifier;
|
||||||
|
if (!bundleIdentifier || !product.darwinProfilePayloadUUID || !product.darwinProfileUUID) {
|
||||||
|
throw new Error(`Missing required product information.`);
|
||||||
|
}
|
||||||
|
const root = '.build/policies/darwin';
|
||||||
|
const { profile, manifests } = await renderMacOSPolicy(policies, translations);
|
||||||
|
await fs_1.promises.rm(root, { recursive: true, force: true });
|
||||||
|
await fs_1.promises.mkdir(root, { recursive: true });
|
||||||
|
await fs_1.promises.writeFile(path_1.default.join(root, `${bundleIdentifier}.mobileconfig`), profile.replace(/\r?\n/g, '\n'));
|
||||||
|
for (const { languageId, contents } of manifests) {
|
||||||
|
const languagePath = path_1.default.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId]);
|
||||||
|
await fs_1.promises.mkdir(languagePath, { recursive: true });
|
||||||
|
await fs_1.promises.writeFile(path_1.default.join(languagePath, `${bundleIdentifier}.plist`), contents.replace(/\r?\n/g, '\n'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function main() {
|
||||||
|
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
|
||||||
|
const platform = process.argv[2];
|
||||||
|
if (platform === 'darwin') {
|
||||||
|
await darwinMain(policies, translations);
|
||||||
|
}
|
||||||
|
else if (platform === 'win32') {
|
||||||
|
await windowsMain(policies, translations);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.error(`Usage: node build/lib/policies <darwin|win32>`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
main().catch(err => {
|
main().catch(err => {
|
||||||
if (err instanceof ParseError) {
|
if (err instanceof ParseError) {
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ interface Policy {
|
|||||||
renderADMX(regKey: string): string[];
|
renderADMX(regKey: string): string[];
|
||||||
renderADMLStrings(translations?: LanguageTranslations): string[];
|
renderADMLStrings(translations?: LanguageTranslations): string[];
|
||||||
renderADMLPresentation(): string;
|
renderADMLPresentation(): string;
|
||||||
|
renderProfile(): string[];
|
||||||
|
// https://github.com/ProfileManifests/ProfileManifests/wiki/Manifest-Format
|
||||||
|
renderProfileManifest(translations?: LanguageTranslations): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderADMLString(prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string {
|
function renderADMLString(prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string {
|
||||||
@@ -68,6 +71,24 @@ function renderADMLString(prefix: string, moduleName: string, nlsString: NlsStri
|
|||||||
return `<string id="${prefix}_${nlsString.nlsKey.replace(/\./g, '_')}">${value}</string>`;
|
return `<string id="${prefix}_${nlsString.nlsKey.replace(/\./g, '_')}">${value}</string>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderProfileString(_prefix: string, moduleName: string, nlsString: NlsString, translations?: LanguageTranslations): string {
|
||||||
|
let value: string | undefined;
|
||||||
|
|
||||||
|
if (translations) {
|
||||||
|
const moduleTranslations = translations[moduleName];
|
||||||
|
|
||||||
|
if (moduleTranslations) {
|
||||||
|
value = moduleTranslations[nlsString.nlsKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
value = nlsString.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
abstract class BasePolicy implements Policy {
|
abstract class BasePolicy implements Policy {
|
||||||
constructor(
|
constructor(
|
||||||
readonly type: PolicyType,
|
readonly type: PolicyType,
|
||||||
@@ -108,6 +129,19 @@ abstract class BasePolicy implements Policy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract renderADMLPresentationContents(): string;
|
protected abstract renderADMLPresentationContents(): string;
|
||||||
|
|
||||||
|
renderProfile() {
|
||||||
|
return [`<key>${this.name}</key>`, this.renderProfileValue()];
|
||||||
|
}
|
||||||
|
|
||||||
|
renderProfileManifest(translations?: LanguageTranslations): string {
|
||||||
|
return `<dict>
|
||||||
|
${this.renderProfileManifestValue(translations)}
|
||||||
|
</dict>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract renderProfileValue(): string;
|
||||||
|
abstract renderProfileManifestValue(translations?: LanguageTranslations): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
class BooleanPolicy extends BasePolicy {
|
class BooleanPolicy extends BasePolicy {
|
||||||
@@ -150,6 +184,23 @@ class BooleanPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
|
return `<checkBox refId="${this.name}">${this.name}</checkBox>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderProfileValue(): string {
|
||||||
|
return `<false/>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderProfileManifestValue(translations?: LanguageTranslations): string {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<false/>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>boolean</string>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParseError extends Error {
|
class ParseError extends Error {
|
||||||
@@ -204,6 +255,23 @@ class NumberPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
|
return `<decimalTextBox refId="${this.name}" defaultValue="${this.defaultValue}">${this.name}</decimalTextBox>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderProfileValue() {
|
||||||
|
return `<integer>${this.defaultValue}</integer>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderProfileManifestValue(translations?: LanguageTranslations) {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<integer>${this.defaultValue}</integer>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>integer</string>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringPolicy extends BasePolicy {
|
class StringPolicy extends BasePolicy {
|
||||||
@@ -242,6 +310,23 @@ class StringPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
|
return `<textBox refId="${this.name}"><label>${this.name}:</label></textBox>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderProfileValue(): string {
|
||||||
|
return `<string></string>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderProfileManifestValue(translations?: LanguageTranslations): string {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<string></string>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ObjectPolicy extends BasePolicy {
|
class ObjectPolicy extends BasePolicy {
|
||||||
@@ -280,6 +365,24 @@ class ObjectPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<multiTextBox refId="${this.name}" />`;
|
return `<multiTextBox refId="${this.name}" />`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderProfileValue(): string {
|
||||||
|
return `<string></string>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderProfileManifestValue(translations?: LanguageTranslations): string {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<string></string>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringEnumPolicy extends BasePolicy {
|
class StringEnumPolicy extends BasePolicy {
|
||||||
@@ -349,6 +452,27 @@ class StringEnumPolicy extends BasePolicy {
|
|||||||
renderADMLPresentationContents() {
|
renderADMLPresentationContents() {
|
||||||
return `<dropdownList refId="${this.name}" />`;
|
return `<dropdownList refId="${this.name}" />`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderProfileValue() {
|
||||||
|
return `<string>${this.enum_[0]}</string>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderProfileManifestValue(translations?: LanguageTranslations): string {
|
||||||
|
return `<key>pfm_default</key>
|
||||||
|
<string>${this.enum_[0]}</string>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${renderProfileString(this.name, this.moduleName, this.description, translations)}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${this.name}</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
<key>pfm_range_list</key>
|
||||||
|
<array>
|
||||||
|
${this.enum_.map(e => `<string>${e}</string>`).join('\n ')}
|
||||||
|
</array>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface QType<T> {
|
interface QType<T> {
|
||||||
@@ -606,6 +730,197 @@ function renderADML(appName: string, versions: string[], categories: Category[],
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderProfileManifest(appName: string, bundleIdentifier: string, _versions: string[], _categories: Category[], policies: Policy[], translations?: LanguageTranslations) {
|
||||||
|
|
||||||
|
const requiredPayloadFields = `
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>Configure ${appName}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadDescription</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Description</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>${appName}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadDisplayName</string>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Display Name</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadIdentifier</string>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Identifier</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadType</string>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Type</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string></string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadUUID</string>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload UUID</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadVersion</string>
|
||||||
|
<key>pfm_range_list</key>
|
||||||
|
<array>
|
||||||
|
<integer>1</integer>
|
||||||
|
</array>
|
||||||
|
<key>pfm_require</key>
|
||||||
|
<string>always</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Version</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>integer</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>pfm_default</key>
|
||||||
|
<string>Microsoft</string>
|
||||||
|
<key>pfm_name</key>
|
||||||
|
<string>PayloadOrganization</string>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>Payload Organization</string>
|
||||||
|
<key>pfm_type</key>
|
||||||
|
<string>string</string>
|
||||||
|
</dict>`;
|
||||||
|
|
||||||
|
const profileManifestSubkeys = policies.map(policy => {
|
||||||
|
return policy.renderProfileManifest(translations);
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>pfm_app_url</key>
|
||||||
|
<string>https://code.visualstudio.com/</string>
|
||||||
|
<key>pfm_description</key>
|
||||||
|
<string>${appName} Managed Settings</string>
|
||||||
|
<key>pfm_documentation_url</key>
|
||||||
|
<string>https://code.visualstudio.com/docs/setup/enterprise</string>
|
||||||
|
<key>pfm_domain</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>pfm_format_version</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>pfm_interaction</key>
|
||||||
|
<string>combined</string>
|
||||||
|
<key>pfm_last_modified</key>
|
||||||
|
<date>${new Date().toISOString().replace(/\.\d+Z$/, 'Z')}</date>
|
||||||
|
<key>pfm_platforms</key>
|
||||||
|
<array>
|
||||||
|
<string>macOS</string>
|
||||||
|
</array>
|
||||||
|
<key>pfm_subkeys</key>
|
||||||
|
<array>
|
||||||
|
${requiredPayloadFields}
|
||||||
|
${profileManifestSubkeys}
|
||||||
|
</array>
|
||||||
|
<key>pfm_title</key>
|
||||||
|
<string>${appName}</string>
|
||||||
|
<key>pfm_unique</key>
|
||||||
|
<true/>
|
||||||
|
<key>pfm_version</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderMacOSPolicy(policies: Policy[], translations: Translations) {
|
||||||
|
const appName = product.nameLong;
|
||||||
|
const bundleIdentifier = product.darwinBundleIdentifier;
|
||||||
|
const payloadUUID = product.darwinProfilePayloadUUID;
|
||||||
|
const UUID = product.darwinProfileUUID;
|
||||||
|
|
||||||
|
const versions = [...new Set(policies.map(p => p.minimumVersion)).values()].sort();
|
||||||
|
const categories = [...new Set(policies.map(p => p.category))];
|
||||||
|
|
||||||
|
const policyEntries =
|
||||||
|
policies.map(policy => policy.renderProfile())
|
||||||
|
.flat()
|
||||||
|
.map(entry => `\t\t\t\t${entry}`)
|
||||||
|
.join('\n');
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
profile: `<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>PayloadContent</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>${appName}</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>${bundleIdentifier}.${UUID}</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>${UUID}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
${policyEntries}
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>This profile manages ${appName}. For more information see https://code.visualstudio.com/docs/setup/enterprise</string>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>${appName}</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>${bundleIdentifier}</string>
|
||||||
|
<key>PayloadOrganization</key>
|
||||||
|
<string>Microsoft</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>${payloadUUID}</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>TargetDeviceType</key>
|
||||||
|
<integer>5</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>`,
|
||||||
|
manifests: [{ languageId: 'en-us', contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies) },
|
||||||
|
...translations.map(({ languageId, languageTranslations }) =>
|
||||||
|
({ languageId, contents: renderProfileManifest(appName, bundleIdentifier, versions, categories, policies, languageTranslations) }))
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function renderGP(policies: Policy[], translations: Translations) {
|
function renderGP(policies: Policy[], translations: Translations) {
|
||||||
const appName = product.nameLong;
|
const appName = product.nameLong;
|
||||||
const regKey = product.win32RegValueName;
|
const regKey = product.win32RegValueName;
|
||||||
@@ -751,18 +1066,10 @@ async function getTranslations(): Promise<Translations> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function windowsMain(policies: Policy[], translations: Translations) {
|
||||||
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
|
const root = '.build/policies/win32';
|
||||||
|
|
||||||
console.log(`Found ${policies.length} policies:`);
|
|
||||||
|
|
||||||
for (const policy of policies) {
|
|
||||||
console.log(`- ${policy.name} (${policy.type})`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { admx, adml } = await renderGP(policies, translations);
|
const { admx, adml } = await renderGP(policies, translations);
|
||||||
|
|
||||||
const root = '.build/policies/win32';
|
|
||||||
await fs.rm(root, { recursive: true, force: true });
|
await fs.rm(root, { recursive: true, force: true });
|
||||||
await fs.mkdir(root, { recursive: true });
|
await fs.mkdir(root, { recursive: true });
|
||||||
|
|
||||||
@@ -775,6 +1082,39 @@ async function main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function darwinMain(policies: Policy[], translations: Translations) {
|
||||||
|
const bundleIdentifier = product.darwinBundleIdentifier;
|
||||||
|
if (!bundleIdentifier || !product.darwinProfilePayloadUUID || !product.darwinProfileUUID) {
|
||||||
|
throw new Error(`Missing required product information.`);
|
||||||
|
}
|
||||||
|
const root = '.build/policies/darwin';
|
||||||
|
const { profile, manifests } = await renderMacOSPolicy(policies, translations);
|
||||||
|
|
||||||
|
await fs.rm(root, { recursive: true, force: true });
|
||||||
|
await fs.mkdir(root, { recursive: true });
|
||||||
|
await fs.writeFile(path.join(root, `${bundleIdentifier}.mobileconfig`), profile.replace(/\r?\n/g, '\n'));
|
||||||
|
|
||||||
|
for (const { languageId, contents } of manifests) {
|
||||||
|
const languagePath = path.join(root, languageId === 'en-us' ? 'en-us' : Languages[languageId as keyof typeof Languages]);
|
||||||
|
await fs.mkdir(languagePath, { recursive: true });
|
||||||
|
await fs.writeFile(path.join(languagePath, `${bundleIdentifier}.plist`), contents.replace(/\r?\n/g, '\n'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const [policies, translations] = await Promise.all([parsePolicies(), getTranslations()]);
|
||||||
|
const platform = process.argv[2];
|
||||||
|
|
||||||
|
if (platform === 'darwin') {
|
||||||
|
await darwinMain(policies, translations);
|
||||||
|
} else if (platform === 'win32') {
|
||||||
|
await windowsMain(policies, translations);
|
||||||
|
} else {
|
||||||
|
console.error(`Usage: node build/lib/policies <darwin|win32>`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (require.main === module) {
|
if (require.main === module) {
|
||||||
main().catch(err => {
|
main().catch(err => {
|
||||||
if (err instanceof ParseError) {
|
if (err instanceof ParseError) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "code-oss-dev",
|
"name": "code-oss-dev",
|
||||||
"version": "1.99.0",
|
"version": "1.99.0",
|
||||||
"distro": "034ea95a21e3eb734fd22bf565a1e2e80d62ea9b",
|
"distro": "c3ec5ba4852b5682b94358c92bf31484d2739db9",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Microsoft Corporation"
|
"name": "Microsoft Corporation"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
"win32TunnelServiceMutex": "vscodeoss-tunnelservice",
|
"win32TunnelServiceMutex": "vscodeoss-tunnelservice",
|
||||||
"win32TunnelMutex": "vscodeoss-tunnel",
|
"win32TunnelMutex": "vscodeoss-tunnel",
|
||||||
"darwinBundleIdentifier": "com.visualstudio.code.oss",
|
"darwinBundleIdentifier": "com.visualstudio.code.oss",
|
||||||
|
"darwinProfileUUID": "47827DD9-4734-49A0-AF80-7E19B11495CC",
|
||||||
|
"darwinProfilePayloadUUID": "CF808BE7-53F3-46C6-A7E2-7EDB98A5E959",
|
||||||
"linuxIconName": "code-oss",
|
"linuxIconName": "code-oss",
|
||||||
"licenseFileName": "LICENSE.txt",
|
"licenseFileName": "LICENSE.txt",
|
||||||
"reportIssueUrl": "https://github.com/microsoft/vscode/issues/new",
|
"reportIssueUrl": "https://github.com/microsoft/vscode/issues/new",
|
||||||
|
|||||||
Reference in New Issue
Block a user