From 90dd67d1c6c014470659733d8ddea4268ed08338 Mon Sep 17 00:00:00 2001 From: Ben Lovy Date: Tue, 14 Jan 2025 10:58:23 -0500 Subject: [PATCH] add rust-plain, python-pyproject tests --- packages/autobuild/python/tangram.ts | 77 +++++++++++++++++++ packages/autobuild/tangram.ts | 55 ++++++++++++- packages/autobuild/tests/python-plain/main.py | 1 + .../tests/python-pyproject/README.md | 3 + .../tests/python-pyproject/pyproject.toml | 20 +++++ .../src/demo_package/__init__.py | 0 .../python-pyproject/src/demo_package/main.py | 10 +++ .../tests/python-pyproject/tests/__init__.py | 0 packages/autobuild/tests/python/README.md | 3 + packages/autobuild/tests/python/setup.cfg | 21 +++++ .../tests/python/src/demo_package/__init__.py | 0 .../tests/python/src/demo_package/main.py | 10 +++ .../autobuild/tests/python/tests/__init__.py | 0 packages/autobuild/tests/rust-plain/main.rs | 3 + packages/python/tangram.ts | 2 +- packages/ruby/tangram.ts | 10 ++- 16 files changed, 207 insertions(+), 8 deletions(-) create mode 100644 packages/autobuild/python/tangram.ts create mode 100644 packages/autobuild/tests/python-plain/main.py create mode 100644 packages/autobuild/tests/python-pyproject/README.md create mode 100644 packages/autobuild/tests/python-pyproject/pyproject.toml create mode 100644 packages/autobuild/tests/python-pyproject/src/demo_package/__init__.py create mode 100644 packages/autobuild/tests/python-pyproject/src/demo_package/main.py create mode 100644 packages/autobuild/tests/python-pyproject/tests/__init__.py create mode 100644 packages/autobuild/tests/python/README.md create mode 100644 packages/autobuild/tests/python/setup.cfg create mode 100644 packages/autobuild/tests/python/src/demo_package/__init__.py create mode 100644 packages/autobuild/tests/python/src/demo_package/main.py create mode 100644 packages/autobuild/tests/python/tests/__init__.py create mode 100644 packages/autobuild/tests/rust-plain/main.rs diff --git a/packages/autobuild/python/tangram.ts b/packages/autobuild/python/tangram.ts new file mode 100644 index 00000000..2517ccda --- /dev/null +++ b/packages/autobuild/python/tangram.ts @@ -0,0 +1,77 @@ +import * as std from "std" with { path: "../../std" }; +import * as python from "python" with { path: "../../python" }; +// import * as poetry from "poetry" with { path: "../../poetry" }; +import { wrapScripts } from "../common"; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const build = tg.target(async (arg: Arg) => { + const { build, env: envArg, host, source } = arg ?? {}; + + const env_ = envArg ?? std.env.arg(env({ build, host }), envArg); + let arg_: python.BuildArg = { build, env: env_, host, source }; + + const maybeRequirements = source.tryGet("requirements.txt"); + if (maybeRequirements) { + if (maybeRequirements instanceof tg.File) { + arg_ = { ...arg_, requirements: maybeRequirements }; + } + } + + return python.build(arg_); +}); + +export default build; + +export const plain = tg.target(async (arg: Arg) => { + const { build, env: envArg, host, source } = arg ?? {}; + + const env_ = envArg ?? std.env.arg(env({ build, host }), envArg); + const toolchain = await python.toolchain(); + const interpreter = await toolchain.get("bin/python3").then(tg.File.expect); + return wrapScripts({ + directory: source, + extension: ".py", + interpreter, + env: std.env.arg( + { + PYTHONPATH: toolchain, + }, + env_, + ), + }); +}); + +// export const poetry = tg.target(async (arg: Arg) => { +// const { build, env: envArg, host, source } = arg ?? {}; + +// const env_ = envArg ?? std.env.arg(env({ build, host }), envArg); +// const arg_ = { build, env: env_, host, source }; +// return poetry.build(arg_); +// }); + +export const pyproject = tg.target(async (arg: Arg) => { + const { build, env: envArg, host, source } = arg ?? {}; + + const env_ = envArg ?? std.env.arg(env({ build, host }), envArg); + const pyprojectToml = await source.get("pyproject.toml").then(tg.File.expect); + const arg_ = { build, env: env_, host, pyprojectToml, source }; + return python.build(arg_); +}); + +type EnvArg = { + build?: string | undefined; + host?: string | undefined; +}; + +export const env = tg.target(async (arg: EnvArg) => { + const { build: build_, host: host_ } = arg ?? {}; + const host = host_ ?? (await std.triple.host()); + const build = build_ ?? host; + return std.env(python.toolchain({ ...std.triple.rotate({ build, host }) })); +}); diff --git a/packages/autobuild/tangram.ts b/packages/autobuild/tangram.ts index 6c4c6c6c..7bf768b2 100644 --- a/packages/autobuild/tangram.ts +++ b/packages/autobuild/tangram.ts @@ -8,6 +8,7 @@ import * as autotools from "./autotools"; import * as cmake from "./cmake"; import * as go from "./go"; import * as js from "./js"; +import * as python from "./python"; import * as rust from "./rust"; import ccAutotoolsTest from "./tests/cc-autotools" with { type: "directory" }; @@ -15,7 +16,13 @@ import cmakeTest from "./tests/cmake" with { type: "directory" }; import goTest from "./tests/go" with { type: "directory" }; import jsNodeTest from "./tests/js-node" with { type: "directory" }; import jsPlainTest from "./tests/js-plain" with { type: "directory" }; +import pythonTest from "./tests/python" with { type: "directory" }; +import pythonPlainTest from "./tests/python-plain" with { type: "directory" }; +import pythonPyprojectTest from "./tests/python-pyproject" with { + type: "directory", +}; import rustCargoTest from "./tests/rust-cargo" with { type: "directory" }; +import rustPlainTest from "./tests/rust-plain" with { type: "directory" }; export const metadata = { name: "autobuild", @@ -57,9 +64,21 @@ export const build = tg.target(async (arg: Arg) => { case "js-plain": { return js.plain(arg_); } + case "python": { + return python.build(arg_); + } + case "python-plain": { + return python.plain(arg_); + } + case "python-pyproject": { + return python.pyproject(arg_); + } case "rust-cargo": { return rust.cargo(arg_); } + case "rust-plain": { + return rust.plain(arg_); + } default: { throw new Error( `unable to autodetect project type, edit your tangram.ts file to define desired behavior`, @@ -98,7 +117,13 @@ export const env = tg.target(async (arg: EnvArg) => { case "js-plain": { return js.env(arg_); } - case "rust-cargo": { + case "python": + case "python-plain": + case "python-pyproject": { + return python.env(arg_); + } + case "rust-cargo": + case "rust-plain": { return rust.env(arg_); } default: { @@ -115,7 +140,11 @@ export type Kind = | "go" | "js-node" | "js-plain" - | "rust-cargo"; + | "python" + | "python-plain" + | "python-pyproject" + | "rust-cargo" + | "rust-plain"; export const detectKind = async (source: tg.Directory): Promise => { const entries = await source.entries(); @@ -137,8 +166,11 @@ export const detectKind = async (source: tg.Directory): Promise => { if (hasExecutableFile("configure") || hasFile("configure.ac")) return "cc-autotools"; if (hasFile("package.json")) return "js-node"; + if (hasFile("pyproject.toml")) return "python-pyproject"; + if (hasFile("setup.py") || hasFile("setup.cfg")) return "python"; if (hasFile("go.mod") || hasDir("vendor")) return "go"; + if (hasFileWithExtension(".py")) return "python-plain"; if (hasFileWithExtension(".rs")) return "rust-plain"; if (hasFileWithExtension(".js")) return "js-plain"; @@ -151,9 +183,10 @@ export const test = tg.target(async () => { "cc-autotools", "cmake", "go", - // "js-node",// failed to creat target without host - phases.build issue? "js-plain", + "python-plain", "rust-cargo", + "rust-plain", ]; await Promise.all(allKinds.map((variant) => testKind(variant))); @@ -190,7 +223,19 @@ const testParamaters = (): Record => { testFile: (buildOutput: tg.Directory): Promise => tg`${buildOutput}/index.js`, }, + python: defaultTestArg, + "python-plain": { + ...defaultTestArg, + testFile: (buildOutput: tg.Directory): Promise => + tg`${buildOutput}/main.py`, + }, + "python-pyproject": defaultTestArg, "rust-cargo": defaultTestArg, + "rust-plain": { + ...defaultTestArg, + testFile: (buildOutput: tg.Directory): Promise => + tg`${buildOutput}/bin/main`, + }, }; }; @@ -202,7 +247,11 @@ const testDirs = async (): Promise> => { go: goTest, "js-node": jsNodeTest, "js-plain": jsPlainTest, + python: pythonTest, + "python-plain": pythonPlainTest, + "python-pyproject": pythonPyprojectTest, "rust-cargo": rustCargoTest, + "rust-plain": rustPlainTest, }; }; diff --git a/packages/autobuild/tests/python-plain/main.py b/packages/autobuild/tests/python-plain/main.py new file mode 100644 index 00000000..f7cf60e1 --- /dev/null +++ b/packages/autobuild/tests/python-plain/main.py @@ -0,0 +1 @@ +print("Hello, world!") diff --git a/packages/autobuild/tests/python-pyproject/README.md b/packages/autobuild/tests/python-pyproject/README.md new file mode 100644 index 00000000..c000e1c5 --- /dev/null +++ b/packages/autobuild/tests/python-pyproject/README.md @@ -0,0 +1,3 @@ +# demo + +A sample Poetry package. diff --git a/packages/autobuild/tests/python-pyproject/pyproject.toml b/packages/autobuild/tests/python-pyproject/pyproject.toml new file mode 100644 index 00000000..90d36ebc --- /dev/null +++ b/packages/autobuild/tests/python-pyproject/pyproject.toml @@ -0,0 +1,20 @@ +[build-system] +requires = ["setuptools>=45", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "demo_package" +version = "0.1.0" +description = "A demonstration package that displays text to stdout" +readme = "README.md" +authors = [ + {name = "Tangram", email = "hello@tangram.dev"} +] +requires-python = ">=3.8" +dependencies = [] + +[project.optional-dependencies] +dev = ["pytest>=7.0"] + +[project.scripts] +test = "demo_package.main:main" diff --git a/packages/autobuild/tests/python-pyproject/src/demo_package/__init__.py b/packages/autobuild/tests/python-pyproject/src/demo_package/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/autobuild/tests/python-pyproject/src/demo_package/main.py b/packages/autobuild/tests/python-pyproject/src/demo_package/main.py new file mode 100644 index 00000000..46cf471f --- /dev/null +++ b/packages/autobuild/tests/python-pyproject/src/demo_package/main.py @@ -0,0 +1,10 @@ +def get_message() -> str: + return "Hello, world!" + +def main() -> None: + """Entry point for the application.""" + message = get_message() + print(message) + +if __name__ == "__main__": + main() diff --git a/packages/autobuild/tests/python-pyproject/tests/__init__.py b/packages/autobuild/tests/python-pyproject/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/autobuild/tests/python/README.md b/packages/autobuild/tests/python/README.md new file mode 100644 index 00000000..c000e1c5 --- /dev/null +++ b/packages/autobuild/tests/python/README.md @@ -0,0 +1,3 @@ +# demo + +A sample Poetry package. diff --git a/packages/autobuild/tests/python/setup.cfg b/packages/autobuild/tests/python/setup.cfg new file mode 100644 index 00000000..1ddd61a2 --- /dev/null +++ b/packages/autobuild/tests/python/setup.cfg @@ -0,0 +1,21 @@ +[metadata] +name = demo-package +version = 0.1.0 +description = A demonstration package that displays text to stdout +long_description = file: README.md +long_description_content_type = text/markdown +author = Tangram +author_email = hello@tangram.dev + +[options] +package_dir = + = src +packages = find: +python_requires = >=3.8 + +[options.packages.find] +where = src + +[options.entry_points] +console_scripts = + demo-text = demo_package.main:main diff --git a/packages/autobuild/tests/python/src/demo_package/__init__.py b/packages/autobuild/tests/python/src/demo_package/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/autobuild/tests/python/src/demo_package/main.py b/packages/autobuild/tests/python/src/demo_package/main.py new file mode 100644 index 00000000..4dcbe93c --- /dev/null +++ b/packages/autobuild/tests/python/src/demo_package/main.py @@ -0,0 +1,10 @@ +def get_message() -> str: + return "Hello world!" + +def main() -> None: + """Entry point for the application.""" + message = get_message() + print(message) + +if __name__ == "__main__": + main() diff --git a/packages/autobuild/tests/python/tests/__init__.py b/packages/autobuild/tests/python/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/autobuild/tests/rust-plain/main.rs b/packages/autobuild/tests/rust-plain/main.rs new file mode 100644 index 00000000..e7a11a96 --- /dev/null +++ b/packages/autobuild/tests/rust-plain/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/packages/python/tangram.ts b/packages/python/tangram.ts index 3dac8ce5..b6fd0714 100644 --- a/packages/python/tangram.ts +++ b/packages/python/tangram.ts @@ -390,7 +390,7 @@ export const build = tg.target(async (...args: std.Args) => { toolchain({ ...pythonArg, build: buildTriple, host }), { ["lib/python3/site-packages"]: { - [name]: tg.symlink(tg`${source}/${name}`), + [name]: tg.symlink(tg`${source}/src/${name}`), }, }, ); diff --git a/packages/ruby/tangram.ts b/packages/ruby/tangram.ts index 4ae0f81b..8b9023be 100644 --- a/packages/ruby/tangram.ts +++ b/packages/ruby/tangram.ts @@ -19,18 +19,20 @@ export const metadata = { name: "ruby", license: "BSD-2-Clause", repository: "https://git.ruby-lang.org/ruby.git", - version: "3.3.0", + version: "3.4.1", }; export const source = tg.target(async () => { const { version } = metadata; const checksum = - "sha256:96518814d9832bece92a85415a819d4893b307db5921ae1f0f751a9a89a56b7d"; + "sha256:3d385e5d22d368b064c817a13ed8e3cc3f71a7705d7ed1bae78013c33aa7c87f"; const extension = ".tar.gz"; const majorMinor = version.split(".").slice(0, 2).join("."); const url = `https://cache.ruby-lang.org/pub/ruby/${majorMinor}/ruby-${version}${extension}`; - const outer = tg.Directory.expect(await std.download({ url, checksum })); - return std.directory.unwrap(outer); + return std + .download({ url, checksum }) + .then(tg.Directory.expect) + .then(std.directory.unwrap); }); export type Arg = {