"""Verify and vendor the unmodified official Monaco 0.52.2 AMD distribution."""
import base64
import hashlib
import json
import pathlib
import tarfile
import urllib.request
ROOT = pathlib.Path(__file__).resolve().parents[2]
VERSION = '0.52.2'
URL = f'https://registry.npmjs.org/monaco-editor/-/monaco-editor-{VERSION}.tgz'
ARCHIVE_SHA256 = 'c280cdcf0b0c13d1a2bf01af958d4387ed06d7f6c918401d00c4adcae1bc72b6'
INTEGRITY = 'sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ=='
DOWNLOAD = ROOT / 'build/BrowserProbe/MonacoDownload'
TARGET = ROOT / f'assets/Browser/Monaco/{VERSION}'
DOWNLOAD.mkdir(parents=True, exist_ok=True)
archive = DOWNLOAD / f'monaco-editor-{VERSION}.tgz'
if not archive.exists():
with urllib.request.urlopen(URL, timeout=60) as response:
archive.write_bytes(response.read(50_000_001))
data = archive.read_bytes()
if len(data) > 50_000_000 or hashlib.sha256(data).hexdigest() != ARCHIVE_SHA256:
raise SystemExit('The Monaco archive does not match the pinned SHA256.')
if 'sha512-' + base64.b64encode(hashlib.sha512(data).digest()).decode() != INTEGRITY:
raise SystemExit('The Monaco archive does not match the published npm SHA512 integrity.')
files = []
with tarfile.open(archive) as package:
for member in package.getmembers():
name = pathlib.PurePosixPath(member.name)
if name.is_absolute() or '..' in name.parts or not member.isfile():
raise SystemExit(f'Unexpected archive member: {member.name}')
if not member.name.startswith('package/min/') and member.name not in (
'package/LICENSE', 'package/ThirdPartyNotices.txt', 'package/package.json'):
continue
relative = pathlib.PurePosixPath(*name.parts[1:])
path = TARGET.joinpath(*relative.parts)
path.parent.mkdir(parents=True, exist_ok=True)
content = package.extractfile(member).read()
path.write_bytes(content)
files.append({'Path': relative.as_posix(), 'Bytes': len(content), 'Sha256': hashlib.sha256(content).hexdigest()})
manifest = {
'Kind': 'OfficialMonacoAmdDistribution', 'Package': 'monaco-editor', 'Version': VERSION,
'RegistryMetadata': f'https://registry.npmjs.org/monaco-editor/{VERSION}',
'Tarball': URL, 'TarballSha256': ARCHIVE_SHA256, 'NpmIntegrity': INTEGRITY,
'License': 'MIT; retain LICENSE and ThirdPartyNotices.txt',
'UpstreamDocumentation': 'https://github.com/microsoft/monaco-editor/blob/v0.52.2/docs/integrate-amd.md',
'Transformations': [], 'Files': sorted(files, key=lambda item: item['Path'])
}
(TARGET / 'Manifest.json').write_text(json.dumps(manifest, indent=2) + '\n', encoding='utf-8')
print(json.dumps({'Path': str(TARGET), 'Files': len(files), 'Bytes': sum(f['Bytes'] for f in files), 'ArchiveSha256': ARCHIVE_SHA256}))
"""Verify and vendor the unmodified official Monaco 0.52.2 AMD distribution."""
import base64
import hashlib
import json
import pathlib
import tarfile
import urllib.request
ROOT = pathlib.Path(__file__).resolve().parents[2]
VERSION = '0.52.2'
URL = f'https://registry.npmjs.org/monaco-editor/-/monaco-editor-{VERSION}.tgz'
ARCHIVE_SHA256 = 'c280cdcf0b0c13d1a2bf01af958d4387ed06d7f6c918401d00c4adcae1bc72b6'
INTEGRITY = 'sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ=='
DOWNLOAD = ROOT / 'build/BrowserProbe/MonacoDownload'
TARGET = ROOT / f'assets/Browser/Monaco/{VERSION}'
DOWNLOAD.mkdir(parents=True, exist_ok=True)
archive = DOWNLOAD / f'monaco-editor-{VERSION}.tgz'
if not archive.exists():
with urllib.request.urlopen(URL, timeout=60) as response:
archive.write_bytes(response.read(50_000_001))
data = archive.read_bytes()
if len(data) > 50_000_000 or hashlib.sha256(data).hexdigest() != ARCHIVE_SHA256:
raise SystemExit('The Monaco archive does not match the pinned SHA256.')
if 'sha512-' + base64.b64encode(hashlib.sha512(data).digest()).decode() != INTEGRITY:
raise SystemExit('The Monaco archive does not match the published npm SHA512 integrity.')
files = []
with tarfile.open(archive) as package:
for member in package.getmembers():
name = pathlib.PurePosixPath(member.name)
if name.is_absolute() or '..' in name.parts or not member.isfile():
raise SystemExit(f'Unexpected archive member: {member.name}')
if not member.name.startswith('package/min/') and member.name not in (
'package/LICENSE', 'package/ThirdPartyNotices.txt', 'package/package.json'):
continue
relative = pathlib.PurePosixPath(*name.parts[1:])
path = TARGET.joinpath(*relative.parts)
path.parent.mkdir(parents=True, exist_ok=True)
content = package.extractfile(member).read()
path.write_bytes(content)
files.append({'Path': relative.as_posix(), 'Bytes': len(content), 'Sha256': hashlib.sha256(content).hexdigest()})
manifest = {
'Kind': 'OfficialMonacoAmdDistribution', 'Package': 'monaco-editor', 'Version': VERSION,
'RegistryMetadata': f'https://registry.npmjs.org/monaco-editor/{VERSION}',
'Tarball': URL, 'TarballSha256': ARCHIVE_SHA256, 'NpmIntegrity': INTEGRITY,
'License': 'MIT; retain LICENSE and ThirdPartyNotices.txt',
'UpstreamDocumentation': 'https://github.com/microsoft/monaco-editor/blob/v0.52.2/docs/integrate-amd.md',
'Transformations': [], 'Files': sorted(files, key=lambda item: item['Path'])
}
(TARGET / 'Manifest.json').write_text(json.dumps(manifest, indent=2) + '\n', encoding='utf-8')
print(json.dumps({'Path': str(TARGET), 'Files': len(files), 'Bytes': sum(f['Bytes'] for f in files), 'ArchiveSha256': ARCHIVE_SHA256}))