ossplate 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/bin/darwin-arm64/ossplate +0 -0
- package/bin/darwin-x64/ossplate +3 -0
- package/bin/linux-x64/ossplate +3 -0
- package/bin/ossplate.js +5 -0
- package/bin/win32-x64/ossplate.exe +3 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +56 -0
- package/package.json +43 -0
- package/scaffold/.github/workflows/ci.yml +76 -0
- package/scaffold/.github/workflows/publish-npm.yml +45 -0
- package/scaffold/.github/workflows/publish.yml +97 -0
- package/scaffold/.gitignore +9 -0
- package/scaffold/CONTRIBUTING.md +30 -0
- package/scaffold/LICENSE +9 -0
- package/scaffold/README.md +73 -0
- package/scaffold/core-rs/Cargo.lock +338 -0
- package/scaffold/core-rs/Cargo.toml +28 -0
- package/scaffold/core-rs/src/main.rs +1609 -0
- package/scaffold/docs/README.md +21 -0
- package/scaffold/docs/customizing-the-template.md +144 -0
- package/scaffold/docs/phase-1-contract.md +52 -0
- package/scaffold/docs/testing.md +71 -0
- package/scaffold/docs/upgrade-plan.md +251 -0
- package/scaffold/ossplate.toml +15 -0
- package/scaffold/scripts/verify.sh +36 -0
- package/scaffold/wrapper-js/README.md +7 -0
- package/scaffold/wrapper-js/bin/darwin-arm64/ossplate +0 -0
- package/scaffold/wrapper-js/bin/darwin-x64/ossplate +3 -0
- package/scaffold/wrapper-js/bin/linux-x64/ossplate +3 -0
- package/scaffold/wrapper-js/bin/ossplate.js +5 -0
- package/scaffold/wrapper-js/bin/win32-x64/ossplate.exe +3 -0
- package/scaffold/wrapper-js/package-lock.json +51 -0
- package/scaffold/wrapper-js/package.json +43 -0
- package/scaffold/wrapper-js/src/index.ts +69 -0
- package/scaffold/wrapper-js/tsconfig.json +14 -0
- package/scaffold/wrapper-py/README.md +7 -0
- package/scaffold/wrapper-py/hatch_build.py +16 -0
- package/scaffold/wrapper-py/pyproject.toml +37 -0
- package/scaffold/wrapper-py/src/ossplate/__init__.py +3 -0
- package/scaffold/wrapper-py/src/ossplate/bin/darwin-arm64/ossplate +0 -0
- package/scaffold/wrapper-py/src/ossplate/bin/darwin-x64/ossplate +3 -0
- package/scaffold/wrapper-py/src/ossplate/bin/linux-x64/ossplate +3 -0
- package/scaffold/wrapper-py/src/ossplate/bin/win32-x64/ossplate.exe +3 -0
- package/scaffold/wrapper-py/src/ossplate/cli.py +55 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Stef <stefdevscore@github.com>",
|
|
3
|
+
"bin": {
|
|
4
|
+
"ossplate": "bin/ossplate.js"
|
|
5
|
+
},
|
|
6
|
+
"description": "A practical baseline for shipping one project across Cargo, npm, and PyPI without starting from scratch every time.",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@types/node": "^24.6.0",
|
|
9
|
+
"typescript": "^5.9.3"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin",
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md",
|
|
15
|
+
"scaffold",
|
|
16
|
+
"scaffold/.gitignore"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"oss",
|
|
20
|
+
"ossplate",
|
|
21
|
+
"cli"
|
|
22
|
+
],
|
|
23
|
+
"license": "Unlicense",
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"name": "ossplate",
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"directory": "wrapper-js",
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/stefdevscore/ossplate"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc -p tsconfig.json",
|
|
36
|
+
"pack:check": "npm pack --dry-run",
|
|
37
|
+
"prepack": "node ../scripts/stage-distribution-assets.mjs",
|
|
38
|
+
"stage:dist": "node ../scripts/stage-distribution-assets.mjs",
|
|
39
|
+
"test": "npm run build && node --test test/cli.test.js"
|
|
40
|
+
},
|
|
41
|
+
"type": "module",
|
|
42
|
+
"version": "0.1.0"
|
|
43
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { accessSync, constants } from "node:fs";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { arch as runtimeArch, platform as runtimePlatform } from "node:os";
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const ENV_OVERRIDE = "OSSPLATE_BINARY";
|
|
9
|
+
const TEMPLATE_ROOT_ENV = "OSSPLATE_TEMPLATE_ROOT";
|
|
10
|
+
const TARGETS: Record<string, Record<string, string>> = {
|
|
11
|
+
darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
|
|
12
|
+
linux: { x64: "linux-x64" },
|
|
13
|
+
win32: { x64: "win32-x64" }
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function resolveOssplateBinary(
|
|
17
|
+
options: { baseDir?: string; platform?: NodeJS.Platform; arch?: string } = {}
|
|
18
|
+
): string {
|
|
19
|
+
const envOverride = process.env[ENV_OVERRIDE];
|
|
20
|
+
if (envOverride) {
|
|
21
|
+
return envOverride;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const platform = options.platform ?? runtimePlatform();
|
|
25
|
+
const arch = options.arch ?? runtimeArch();
|
|
26
|
+
const target = TARGETS[platform]?.[arch];
|
|
27
|
+
if (!target) {
|
|
28
|
+
throw new Error(`Unsupported platform/arch: ${platform}/${arch}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const executable = platform === "win32" ? "ossplate.exe" : "ossplate";
|
|
32
|
+
const baseDir = options.baseDir ?? join(__dirname, "..");
|
|
33
|
+
const packagedPath = join(baseDir, "bin", target, executable);
|
|
34
|
+
assertExecutable(packagedPath);
|
|
35
|
+
return packagedPath;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function runOssplate(
|
|
39
|
+
args: string[] = [],
|
|
40
|
+
options: { baseDir?: string; platform?: NodeJS.Platform; arch?: string } = {}
|
|
41
|
+
): void {
|
|
42
|
+
const binPath = resolveOssplateBinary(options);
|
|
43
|
+
const baseDir = options.baseDir ?? join(__dirname, "..");
|
|
44
|
+
const child = spawn(binPath, args, {
|
|
45
|
+
stdio: "inherit",
|
|
46
|
+
env: {
|
|
47
|
+
...process.env,
|
|
48
|
+
[TEMPLATE_ROOT_ENV]:
|
|
49
|
+
process.env[TEMPLATE_ROOT_ENV] ?? join(baseDir, "scaffold")
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
child.on("exit", (code) => {
|
|
54
|
+
process.exit(code ?? 0);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
child.on("error", (error) => {
|
|
58
|
+
console.error(`ossplate: ${error.message}`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function assertExecutable(filePath: string): void {
|
|
64
|
+
try {
|
|
65
|
+
accessSync(filePath, constants.X_OK);
|
|
66
|
+
} catch {
|
|
67
|
+
throw new Error(`Bundled ossplate binary not found or not executable at ${filePath}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*.ts"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Python Wrapper For Ossplate
|
|
2
|
+
|
|
3
|
+
This package is the Python wrapper surface for Ossplate.
|
|
4
|
+
|
|
5
|
+
It delegates to the canonical Rust binary instead of implementing its own CLI behavior.
|
|
6
|
+
|
|
7
|
+
Use `OSSPLATE_BINARY` during local development to point the wrapper at a specific binary.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CustomBuildHook(BuildHookInterface):
|
|
10
|
+
def initialize(self, version: str, build_data: dict) -> None:
|
|
11
|
+
repo_root = Path(self.root).resolve().parent
|
|
12
|
+
script = repo_root / "scripts" / "stage-distribution-assets.mjs"
|
|
13
|
+
try:
|
|
14
|
+
subprocess.run(["node", str(script)], cwd=repo_root, check=True)
|
|
15
|
+
except FileNotFoundError as error:
|
|
16
|
+
raise RuntimeError("node is required to stage distribution assets for wrapper-py builds") from error
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ossplate"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A practical baseline for shipping one project across Cargo, npm, and PyPI without starting from scratch every time."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "Unlicense" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Stef", email = "stefdevscore@github.com" }
|
|
14
|
+
]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"License :: Public Domain",
|
|
18
|
+
"Operating System :: OS Independent"
|
|
19
|
+
]
|
|
20
|
+
dependencies = []
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://github.com/stefdevscore/ossplate"
|
|
24
|
+
Repository = "https://github.com/stefdevscore/ossplate"
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
ossplate = "ossplate.cli:main"
|
|
28
|
+
|
|
29
|
+
[tool.hatch.build.targets.wheel]
|
|
30
|
+
packages = ["src/ossplate"]
|
|
31
|
+
artifacts = [
|
|
32
|
+
"src/ossplate/bin/**",
|
|
33
|
+
"src/ossplate/scaffold/**",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[tool.hatch.build.hooks.custom]
|
|
37
|
+
path = "hatch_build.py"
|
|
Binary file
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import platform
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from importlib import resources
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
ENV_OVERRIDE = "OSSPLATE_BINARY"
|
|
11
|
+
TEMPLATE_ROOT_ENV = "OSSPLATE_TEMPLATE_ROOT"
|
|
12
|
+
TARGETS = {
|
|
13
|
+
("Darwin", "arm64"): ("darwin-arm64", "ossplate"),
|
|
14
|
+
("Darwin", "x86_64"): ("darwin-x64", "ossplate"),
|
|
15
|
+
("Linux", "x86_64"): ("linux-x64", "ossplate"),
|
|
16
|
+
("Windows", "AMD64"): ("win32-x64", "ossplate.exe"),
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_packaged_binary_path(base_dir: Path | None = None) -> str:
|
|
21
|
+
base_dir = base_dir or Path(resources.files("ossplate"))
|
|
22
|
+
env_override = os.environ.get(ENV_OVERRIDE)
|
|
23
|
+
if env_override:
|
|
24
|
+
return env_override
|
|
25
|
+
|
|
26
|
+
system = platform.system()
|
|
27
|
+
machine = platform.machine()
|
|
28
|
+
target = TARGETS.get((system, machine))
|
|
29
|
+
if target is None:
|
|
30
|
+
raise RuntimeError(f"Unsupported platform/arch: {system}/{machine}")
|
|
31
|
+
|
|
32
|
+
folder, executable = target
|
|
33
|
+
binary_path = base_dir / "bin" / folder / executable
|
|
34
|
+
if not binary_path.exists():
|
|
35
|
+
raise RuntimeError(f"Bundled ossplate binary not found at {binary_path}")
|
|
36
|
+
return str(binary_path)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_binary_path() -> str:
|
|
40
|
+
return get_packaged_binary_path()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def cli(args: tuple[str, ...]) -> int:
|
|
44
|
+
env = os.environ.copy()
|
|
45
|
+
env.setdefault(TEMPLATE_ROOT_ENV, str(Path(resources.files("ossplate")) / "scaffold"))
|
|
46
|
+
result = subprocess.run([get_binary_path(), *args], check=False, env=env)
|
|
47
|
+
return result.returncode
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main() -> None:
|
|
51
|
+
raise SystemExit(cli(tuple(sys.argv[1:])))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
if __name__ == "__main__":
|
|
55
|
+
main()
|