diff --git a/Makefile b/Makefile index 880f07d..520f035 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,10 @@ build/packages: mkdir -p $@ node tools/stage-for-pnpn.mjs package-manifest.yaml source $@ +publish: + cd build/packages && ./publish-all.sh + clean: rm -rf build -.PHONY: clean build/packages \ No newline at end of file +.PHONY: clean build/packages publish \ No newline at end of file diff --git a/documentation/errors/readme.md b/documentation/errors/readme.md new file mode 100644 index 0000000..819f95c --- /dev/null +++ b/documentation/errors/readme.md @@ -0,0 +1,3 @@ +# @efforting.tech/errors + +This package defines common errors used throughout the library. diff --git a/package-manifest.yaml b/package-manifest.yaml index 07e6de4..a2dce01 100644 --- a/package-manifest.yaml +++ b/package-manifest.yaml @@ -6,7 +6,7 @@ packages: path: source/errors.mjs documentation: documentation/errors description: Library wide error definitions - version: 0.1.0 + version: 0.1.2 wip-packages: object-graph-storage: diff --git a/tools/stage-for-pnpn.mjs b/tools/stage-for-pnpn.mjs index 8d0b171..c7a33ca 100644 --- a/tools/stage-for-pnpn.mjs +++ b/tools/stage-for-pnpn.mjs @@ -1,5 +1,5 @@ import { parse as parse_yaml, stringify as format_yaml } from 'yaml'; -import { readFileSync, writeFileSync, readdirSync, mkdirSync, symlinkSync, statSync, readlinkSync } from 'node:fs'; +import { unlinkSync, linkSync, chmodSync, readFileSync, writeFileSync, readdirSync, mkdirSync, symlinkSync, statSync, readlinkSync } from 'node:fs'; import path from 'node:path'; const [manifest_file, source, output_directory] = process.argv.slice(2); @@ -50,6 +50,51 @@ function symlink_tree(src, dest) { } +function link_tree(src, dest) { + mkdirSync(dest, { recursive: true }); + if (statSync(src).isDirectory()) { + const result = []; + for (const entry of readdirSync(src, { withFileTypes: true })) { + + const src_path = path.resolve(path.join(src, entry.name)); + const dest_path = path.join(dest, entry.name); + if (entry.isDirectory()) { + result.push(...link_tree(src_path, dest_path)); + } else { + + try { + linkSync(src_path, dest_path); + } catch (e) { + if (e.code === 'EEXIST') { + unlinkSync(dest_path); + linkSync(src_path, dest_path); + } else { + throw e; + } + } + result.push(dest_path); + } + } + return result; + } else { + const link_dest = path.join(dest, path.basename(src)); + const link_src = src; + //console.log('SYMLINK', link_src, link_dest); + //TODO: make a utility function for this + try { + linkSync(link_src, link_dest); + } catch (e) { + if (e.code === 'EEXIST') { + unlinkSync(link_dest); + linkSync(link_src, link_dest); + } else { + throw e; + } + } + return [link_dest]; + } +} + const workspace_manifest = { packages: [], }; @@ -59,6 +104,10 @@ const root_package = { version: '0.1.0', //TODO: Not hardcode? What does this version even represent? type: 'module', dependencies: {}, + publishConfig: { + registry: 'https://npm.efforting.tech/', //TODO: Get from manifest + }, + author: 'mikael-lovqvist', //TODO: Get from manifest }; for (const [package_name, package_data] of Object.entries(manifest.packages)) { @@ -68,10 +117,12 @@ for (const [package_name, package_data] of Object.entries(manifest.packages)) { workspace_manifest.packages.push(pkg.name); const pkg_dir = path.join(output_directory, pkg.name); - const symlinked_files = symlink_tree(pkg.path, pkg_dir).map(p => path.relative(pkg_dir, p)); + const linked_sources = link_tree(pkg.path, pkg_dir).map(p => path.relative(pkg_dir, p)); + const linked_docs = link_tree(pkg.documentation, pkg_dir).map(p => path.relative(pkg_dir, p)); + //console.log('DOCS', { linked_docs }); const exports_map = {}; - for (const file of symlinked_files) { + for (const file of linked_sources) { const name = path.basename(file, '.mjs'); const key = name === pkg.name ? '.' : `./${name}`; exports_map[key] = `./${file}`; @@ -83,11 +134,14 @@ for (const [package_name, package_data] of Object.entries(manifest.packages)) { version, description, type: 'module', exports: exports_map, - + author: 'mikael-lovqvist', //TODO: Get from manifest + publishConfig: { + registry: 'https://npm.efforting.tech/', //TODO: Get from manifest + }, }, null, ' '); writeFileSync(path.join(pkg_dir, 'package.json'), pkg_json, 'utf-8'); - //console.log({symlinked_files}); // ['errors.mjs'] + //console.log({linked_sources}); // ['errors.mjs'] root_package.dependencies[pkg_scope_path] = 'workspace:*'; @@ -96,5 +150,22 @@ for (const [package_name, package_data] of Object.entries(manifest.packages)) { const root_pkg_json = JSON.stringify(root_package, null, ' '); writeFileSync(path.join(output_directory, 'package.json'), root_pkg_json, 'utf-8'); - writeFileSync(path.join(output_directory, 'pnpm-workspace.yaml'), format_yaml(workspace_manifest), 'utf-8'); + +const publish_tool = 'pnpm publish --no-git-checks'; +const publish_script_lines = workspace_manifest.packages.map( + pkg => `${publish_tool} ${pkg}` +); + + +const publish_script = ( + '#!/usr/bin/env bash\n' + + 'set -e\n' + + `${publish_script_lines.join('\n')}\n` +); + +const publish_script_path = path.join(output_directory, 'publish-all.sh'); +writeFileSync(publish_script_path, publish_script, 'utf-8'); +chmodSync(publish_script_path, 0o755); + +