Files
standardnotes-app-web/packages/components/scripts/package.mjs
2022-06-27 14:08:33 -05:00

164 lines
4.9 KiB
JavaScript

import fs from 'fs'
import path from 'path'
import crypto from 'crypto'
import { spawnSync as spawn } from 'child_process'
import zip from '@standardnotes/deterministic-zip'
import minimatch from 'minimatch'
import { Components } from '../dist/Components.js'
import { fileURLToPath } from 'url'
import { ensureDirExists, doesDirExist, emptyExistingDir } from '../../../scripts/ScriptUtils.mjs'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
console.log('Beginning packaging procedure...')
const SourceFilesPath = path.join(__dirname, '../src/Packages')
const DistDir = path.join(__dirname, '../dist')
const TmpDir = path.join(__dirname, '../tmp')
const ZipsDir = path.join(DistDir, '/zips')
const AssetsDir = path.join(DistDir, '/assets')
const ChecksumsSrcPath = path.join(ZipsDir, 'checksums.json')
const ChecksumsDistPath = path.join(ZipsDir, 'checksums.json')
const Checksums = JSON.parse(fs.readFileSync(ChecksumsSrcPath).toString())
console.log('Loaded existing checksums from', ChecksumsSrcPath)
async function zipDirectory(sourceDir, outPath) {
return new Promise((resolve) => {
zip(sourceDir, outPath, { cwd: sourceDir }, (err) => {
console.log(`Zipped to ${outPath}`)
resolve(outPath)
})
})
}
const copyFileOrDir = (src, dest, exludedFilesGlob) => {
const isDir = fs.lstatSync(src).isDirectory()
if (isDir) {
ensureDirExists(dest)
const entries = fs.readdirSync(src, { withFileTypes: true })
for (const entry of entries) {
const srcPath = path.join(src, entry.name)
const excluded = exludedFilesGlob && minimatch(srcPath, exludedFilesGlob)
if (excluded) {
console.log('Excluding file', srcPath)
continue
}
const destPath = path.join(dest, entry.name)
entry.isDirectory() ? copyFileOrDir(srcPath, destPath) : fs.copyFileSync(srcPath, destPath)
}
} else {
const excluded = exludedFilesGlob && minimatch(src, exludedFilesGlob)
if (excluded) {
console.log('Excluding file', src)
return
}
fs.copyFileSync(src, dest)
}
}
const getComponentSrcPath = (feature) => {
return path.join(SourceFilesPath, feature.path)
}
const copyComponentAssets = async (feature, destination, exludedFilesGlob) => {
const srcComponentPath = getComponentSrcPath(feature)
if (!doesDirExist(srcComponentPath)) {
return false
}
emptyExistingDir(destination)
ensureDirExists(destination)
for (const file of feature.static_files) {
const srcFilePath = path.join(srcComponentPath, file)
if (!fs.existsSync(srcFilePath)) {
continue
}
const targetFilePath = path.join(destination, file)
copyFileOrDir(srcFilePath, targetFilePath, exludedFilesGlob)
}
return true
}
const computeChecksum = async (zipPath, version) => {
const zipData = fs.readFileSync(zipPath, 'base64')
const base64 = crypto.createHash('sha256').update(zipData).digest('hex')
const checksumProcess = spawn('sha256sum', [zipPath])
const checksumString = checksumProcess.stdout.toString()
const binary = checksumString.split(' ')[0]
return {
version,
base64,
binary,
}
}
const packageFeature = async ({ feature, noZip }) => {
console.log('Processing feature', feature.identifier, '...')
const assetsLocation = `${path.join(AssetsDir, feature.identifier)}`
const assetsSuccess = await copyComponentAssets(feature, assetsLocation, '**/package.json')
if (!assetsSuccess) {
console.log('Failed to copy assets for', feature.identifier)
return
}
if (noZip) {
console.log('Input arg noZip detected; not zipping asset.')
return
}
const zipAssetsTmpLocation = `${path.join(TmpDir, feature.identifier)}`
const zipAssetsSuccess = await copyComponentAssets(feature, zipAssetsTmpLocation)
if (!zipAssetsSuccess) {
console.log('Failed to copy zip assets for', feature.identifier)
return
}
const zipDestination = `${ZipsDir}/${feature.identifier}.zip`
await zipDirectory(zipAssetsTmpLocation, zipDestination)
const packageJsonFilePath = path.join(getComponentSrcPath(feature), 'package.json')
const packageJsonFile = JSON.parse(fs.readFileSync(packageJsonFilePath).toString())
const checksum = await computeChecksum(zipDestination, packageJsonFile.version)
Checksums[feature.identifier] = checksum
console.log(`Computed checksums for ${feature.identifier}:`, checksum)
}
await (async () => {
const args = process.argv[2] || ''
const noZip = args.includes('--no-zip')
let index = 0
for (const feature of Components) {
if (index === 0) {
console.log('\n---\n')
}
await packageFeature({ feature, noZip })
if (index !== Components.length - 1) {
console.log('\n---\n')
}
index++
}
fs.writeFileSync(ChecksumsSrcPath, JSON.stringify(Checksums, undefined, 2))
copyFileOrDir(ChecksumsSrcPath, ChecksumsDistPath)
console.log('Succesfully wrote checksums to', ChecksumsSrcPath)
emptyExistingDir(TmpDir)
})()