From f089dc28552e20726f47d1a3aa2f7f9399dca0ea Mon Sep 17 00:00:00 2001 From: Ben Lovy Date: Wed, 18 Sep 2024 16:33:08 -0400 Subject: [PATCH] feat(magic): initial detection rules --- packages/autobuild/autotools/tangram.ts | 23 ++ packages/autobuild/cc/tangram.ts | 18 ++ packages/autobuild/cmake/tangram.ts | 18 ++ packages/autobuild/go/tangram.ts | 18 ++ packages/autobuild/js/tangram.ts | 18 ++ packages/autobuild/python-poetry/tangram.ts | 18 ++ packages/autobuild/python/tangram.ts | 18 ++ packages/autobuild/ruby/tangram.ts | 18 ++ packages/autobuild/rust/tangram.ts | 18 ++ packages/autobuild/tangram.ts | 286 ++++++++++++++++++ packages/autobuild/tests/c-plain/main.c | 7 + .../autobuild/tests/cc-autotools/Makefile.am | 2 + packages/autobuild/tests/cc-autotools/README | 1 + .../autobuild/tests/cc-autotools/configure.ac | 9 + .../tests/cc-autotools/src/Makefile.am | 2 + .../autobuild/tests/cc-autotools/src/main.c | 7 + packages/autobuild/tests/cmake/CMakeLists.txt | 9 + packages/autobuild/tests/cmake/src/main.cpp | 7 + packages/autobuild/tests/cxx-plain/main.cxx | 7 + .../autobuild/tests/fortran-plain/main.f90 | 3 + packages/autobuild/tests/go/go.mod | 3 + packages/autobuild/tests/go/hello.go | 7 + packages/autobuild/tests/js-node/main.js | 2 + packages/autobuild/tests/js-node/package.json | 9 + packages/autobuild/tests/js-plain/index.js | 2 + packages/autobuild/tests/python-plain/main.py | 1 + .../autobuild/tests/python-poetry/README.md | 3 + .../tests/python-poetry/pyproject.toml | 20 ++ .../src/demo_package/__init__.py | 0 .../python-poetry/src/demo_package/main.py | 10 + .../tests/python-poetry/tests/__init__.py | 0 .../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/ruby-gem/.gitignore | 8 + packages/autobuild/tests/ruby-gem/Gemfile | 6 + packages/autobuild/tests/ruby-gem/README.md | 35 +++ packages/autobuild/tests/ruby-gem/Rakefile | 2 + packages/autobuild/tests/ruby-gem/bin/console | 14 + packages/autobuild/tests/ruby-gem/bin/setup | 8 + .../autobuild/tests/ruby-gem/lib/ruby/gem.rb | 8 + .../tests/ruby-gem/lib/ruby/gem/version.rb | 5 + .../autobuild/tests/ruby-gem/ruby-gem.gemspec | 40 +++ packages/autobuild/tests/ruby-plain/main.rb | 1 + .../autobuild/tests/rust-cargo/Cargo.lock | 7 + .../autobuild/tests/rust-cargo/Cargo.toml | 6 + .../autobuild/tests/rust-cargo/src/main.rs | 3 + packages/autobuild/tests/rust-plain/main.rs | 3 + packages/autobuild/tests/ts-plain/main.ts | 2 + packages/autobuild/ts/tangram.ts | 18 ++ 57 files changed, 797 insertions(+) create mode 100644 packages/autobuild/autotools/tangram.ts create mode 100644 packages/autobuild/cc/tangram.ts create mode 100644 packages/autobuild/cmake/tangram.ts create mode 100644 packages/autobuild/go/tangram.ts create mode 100644 packages/autobuild/js/tangram.ts create mode 100644 packages/autobuild/python-poetry/tangram.ts create mode 100644 packages/autobuild/python/tangram.ts create mode 100644 packages/autobuild/ruby/tangram.ts create mode 100644 packages/autobuild/rust/tangram.ts create mode 100644 packages/autobuild/tangram.ts create mode 100644 packages/autobuild/tests/c-plain/main.c create mode 100644 packages/autobuild/tests/cc-autotools/Makefile.am create mode 100644 packages/autobuild/tests/cc-autotools/README create mode 100644 packages/autobuild/tests/cc-autotools/configure.ac create mode 100644 packages/autobuild/tests/cc-autotools/src/Makefile.am create mode 100644 packages/autobuild/tests/cc-autotools/src/main.c create mode 100644 packages/autobuild/tests/cmake/CMakeLists.txt create mode 100644 packages/autobuild/tests/cmake/src/main.cpp create mode 100644 packages/autobuild/tests/cxx-plain/main.cxx create mode 100644 packages/autobuild/tests/fortran-plain/main.f90 create mode 100644 packages/autobuild/tests/go/go.mod create mode 100644 packages/autobuild/tests/go/hello.go create mode 100644 packages/autobuild/tests/js-node/main.js create mode 100644 packages/autobuild/tests/js-node/package.json create mode 100644 packages/autobuild/tests/js-plain/index.js create mode 100644 packages/autobuild/tests/python-plain/main.py create mode 100644 packages/autobuild/tests/python-poetry/README.md create mode 100644 packages/autobuild/tests/python-poetry/pyproject.toml create mode 100644 packages/autobuild/tests/python-poetry/src/demo_package/__init__.py create mode 100644 packages/autobuild/tests/python-poetry/src/demo_package/main.py create mode 100644 packages/autobuild/tests/python-poetry/tests/__init__.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/ruby-gem/.gitignore create mode 100644 packages/autobuild/tests/ruby-gem/Gemfile create mode 100644 packages/autobuild/tests/ruby-gem/README.md create mode 100644 packages/autobuild/tests/ruby-gem/Rakefile create mode 100755 packages/autobuild/tests/ruby-gem/bin/console create mode 100755 packages/autobuild/tests/ruby-gem/bin/setup create mode 100644 packages/autobuild/tests/ruby-gem/lib/ruby/gem.rb create mode 100644 packages/autobuild/tests/ruby-gem/lib/ruby/gem/version.rb create mode 100644 packages/autobuild/tests/ruby-gem/ruby-gem.gemspec create mode 100644 packages/autobuild/tests/ruby-plain/main.rb create mode 100644 packages/autobuild/tests/rust-cargo/Cargo.lock create mode 100644 packages/autobuild/tests/rust-cargo/Cargo.toml create mode 100644 packages/autobuild/tests/rust-cargo/src/main.rs create mode 100644 packages/autobuild/tests/rust-plain/main.rs create mode 100644 packages/autobuild/tests/ts-plain/main.ts create mode 100644 packages/autobuild/ts/tangram.ts diff --git a/packages/autobuild/autotools/tangram.ts b/packages/autobuild/autotools/tangram.ts new file mode 100644 index 00000000..f751ad9f --- /dev/null +++ b/packages/autobuild/autotools/tangram.ts @@ -0,0 +1,23 @@ +import * as std from "std" with { path: "../../std" }; +import { $ } from "std" with { path: "../../std" }; + +import * as autoconf from "autoconf" with { path: "../../autoconf" }; +import * as automake from "automake" with { path: "../../automake" }; +import * as gettext from "gettext" with { path: "../../gettext" }; +import * as help2man from "help2man" with { path: "../../help2man" }; +import * as perl from "perl" with { path: "../../perl" }; +import * as texinfo from "texinfo" with { path: "../../texinfo" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + // TODO - compbine env with the imported tools. + return std.autotools.build(arg); +}); + +export default default_; diff --git a/packages/autobuild/cc/tangram.ts b/packages/autobuild/cc/tangram.ts new file mode 100644 index 00000000..06f52f63 --- /dev/null +++ b/packages/autobuild/cc/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return tg.unimplemented(); +}); + +export default default_; + +export const test = tg.target(async () => { + return tg.unimplemented(); +}); diff --git a/packages/autobuild/cmake/tangram.ts b/packages/autobuild/cmake/tangram.ts new file mode 100644 index 00000000..06f52f63 --- /dev/null +++ b/packages/autobuild/cmake/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return tg.unimplemented(); +}); + +export default default_; + +export const test = tg.target(async () => { + return tg.unimplemented(); +}); diff --git a/packages/autobuild/go/tangram.ts b/packages/autobuild/go/tangram.ts new file mode 100644 index 00000000..3b599b77 --- /dev/null +++ b/packages/autobuild/go/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; +import { $ } from "std" with { path: "../../std" }; +import * as go from "go" with { path: "../../go" }; + +// FIXME - this file seems unnecessary + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return go.build(arg); +}); + +export default default_; diff --git a/packages/autobuild/js/tangram.ts b/packages/autobuild/js/tangram.ts new file mode 100644 index 00000000..06f52f63 --- /dev/null +++ b/packages/autobuild/js/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return tg.unimplemented(); +}); + +export default default_; + +export const test = tg.target(async () => { + return tg.unimplemented(); +}); diff --git a/packages/autobuild/python-poetry/tangram.ts b/packages/autobuild/python-poetry/tangram.ts new file mode 100644 index 00000000..06f52f63 --- /dev/null +++ b/packages/autobuild/python-poetry/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return tg.unimplemented(); +}); + +export default default_; + +export const test = tg.target(async () => { + return tg.unimplemented(); +}); diff --git a/packages/autobuild/python/tangram.ts b/packages/autobuild/python/tangram.ts new file mode 100644 index 00000000..06f52f63 --- /dev/null +++ b/packages/autobuild/python/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return tg.unimplemented(); +}); + +export default default_; + +export const test = tg.target(async () => { + return tg.unimplemented(); +}); diff --git a/packages/autobuild/ruby/tangram.ts b/packages/autobuild/ruby/tangram.ts new file mode 100644 index 00000000..06f52f63 --- /dev/null +++ b/packages/autobuild/ruby/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return tg.unimplemented(); +}); + +export default default_; + +export const test = tg.target(async () => { + return tg.unimplemented(); +}); diff --git a/packages/autobuild/rust/tangram.ts b/packages/autobuild/rust/tangram.ts new file mode 100644 index 00000000..06f52f63 --- /dev/null +++ b/packages/autobuild/rust/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return tg.unimplemented(); +}); + +export default default_; + +export const test = tg.target(async () => { + return tg.unimplemented(); +}); diff --git a/packages/autobuild/tangram.ts b/packages/autobuild/tangram.ts new file mode 100644 index 00000000..b19de19c --- /dev/null +++ b/packages/autobuild/tangram.ts @@ -0,0 +1,286 @@ +import * as std from "std" with { path: "../std" }; +import { $ } from "std" with { path: "../std" }; + +import autoconf from "autoconf" with { path: "../autoconf" }; +import automake from "automake" with { path: "../automake" }; + +import * as autotools from "./autotools"; +import * as cc from "./cc"; +import * as cmake from "./cmake"; +import * as go from "./go"; +import * as js from "./js"; +import * as python from "./python"; +import * as ruby from "./ruby"; +import * as rust from "./rust"; +import * as ts from "./ts"; + +import tests from "./tests" with { type: "directory" }; + +export const metadata = { + name: "autobuild", + version: "0.0.0", +}; + +export type Arg = { + build?: string; + env?: std.env.Arg; + kind?: Kind; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + const { source } = arg; + const sourceId = await source.id(); + console.log("received source dir", sourceId); + const kind = await detectKind(source); + + switch (kind) { + case "cc-autotools": { + return autotools.default_(arg); + } + case "c-plain": { + return tg.unimplemented(); + } + case "cxx-plain": { + return tg.unimplemented(); + } + case "fortran-plain": { + return tg.unimplemented(); + } + case "cmake": { + return cmake.default_(arg); + } + case "go": { + return go.default_(arg); + } + case "js-node": { + // return js.node(arg); + return tg.unimplemented(); + } + case "js-plain": { + // const toolchain = await nodejs.toolchain(); + // const interpreter = await toolchain.get("bin/node").then(tg.File.expect); + // return wrapScripts({ directory: source, extension: ".js", interpreter }); + // return js.plain(arg); + return tg.unimplemented(); + } + case "python": { + // return python.default_(arg); + return tg.unimplemented(); + } + case "python-plain": { + // const toolchain = await python.toolchain(); + // const interpreter = await toolchain + // .get("bin/python3") + // .then(tg.File.expect); + // return wrapScripts({ + // directory: source, + // extension: ".py", + // interpreter, + // env: { + // PYTHONPATH: toolchain, + // }, + // }); + // return python.plain({ source }); + return tg.unimplemented(); + } + case "python-poetry": { + // return python.poetry({ source }); + return tg.unimplemented(); + } + case "python-pyproject": { + // const pyprojectToml = await source + // .get("pyproject.toml") + // .then(tg.File.expect); + // return python.pyproject({ source }); + return tg.unimplemented(); + } + case "ruby-gem": { + // return ruby.gem({ source }); + return tg.unimplemented(); + } + case "ruby-plain": { + // const toolchain = await ruby.toolchain(); + // const interpreter = await toolchain.get("bin/ruby").then(tg.File.expect); + // return wrapScripts({ directory: source, extension: ".rb", interpreter }); + // return ruby.plain({ source }); + return tg.unimplemented(); + } + case "rust-cargo": { + // return rust.cargo({ source }); + return tg.unimplemented(); + } + case "rust-plain": { + // return rust.plain({ source }); + return tg.unimplemented(); + } + case "ts-plain": { + // const toolchain = await bun.toolchain(); + // const interpreter = await toolchain.get("bin/bun").then(tg.File.expect); + // return wrapScripts({ directory: source, extension: ".ts", interpreter }); + // return ts.default_({ source }); + return tg.unimplemented(); + } + case "unknown": + default: { + throw new Error( + `unable to autodetect project type, edit your tangram.ts file to define desired behavior`, + ); + } + } +}); + +export default default_; + +export type Kind = + | "cc-autotools" + | "c-plain" + | "cxx-plain" + | "fortran-plain" + | "cmake" + | "go" + | "js-node" + | "js-plain" + | "python" + | "python-plain" + | "python-poetry" + | "python-pyproject" + | "ruby-gem" + | "ruby-plain" + | "rust-cargo" + | "rust-plain" + | "ts-plain" + | "unknown"; + +export const detectKind = async (source: tg.Directory): Promise => { + const entries = await source.entries(); + const hasFile = (name: string) => + entries.hasOwnProperty(name) && entries[name] instanceof tg.File; + const hasExecutableFile = (name: string) => + entries.hasOwnProperty(name) && + entries[name] instanceof tg.File && + entries[name].executable(); + const hasDir = (name: string) => + entries.hasOwnProperty(name) && entries[name] instanceof tg.Directory; + const hasFileWithExtension = (ext: string) => + Object.entries(entries).some( + ([name, artifact]) => artifact instanceof tg.File && name.endsWith(ext), + ); + + if (hasFile("Cargo.toml")) return "rust-cargo"; + if (hasFile("CMakeLists.txt")) return "cmake"; + 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("poetry.lock")) return "python-poetry"; + if (hasFile("setup.py") || hasFile("setup.cfg")) return "python"; + if (hasFile("go.mod") || hasDir("vendor")) return "go"; + if (hasFile("Gemfile")) return "ruby-gem"; + + if (hasFileWithExtension(".rb")) return "ruby-plain"; + if (hasFileWithExtension(".rs")) return "rust-plain"; + if (hasFileWithExtension(".py")) return "python-plain"; + if (hasFileWithExtension(".js")) return "js-plain"; + if (hasFileWithExtension(".ts")) return "ts-plain"; + if ( + hasFileWithExtension(".f90") || + hasFileWithExtension(".f77") || + hasFileWithExtension(".f") || + hasFileWithExtension(".for") + ) + return "fortran-plain"; + if (hasFileWithExtension(".cxx") || hasFileWithExtension(".cpp")) + return "cxx-plain"; + if (hasFileWithExtension(".c")) return "c-plain"; + + // We didn't match any known types. + return "unknown"; +}; + +// TODO +// dir with no runnable files +// meson +// php +// dirs with multiple types of files + +export const test = tg.target(async () => { + const allVariants: Array = [ + "cc-autotools", + "c-plain", + "cxx-plain", + "fortran-plain", + "cmake", + "go", + "js-node", + "js-plain", + "python", + "python-plain", + "python-poetry", + "python-pyproject", + "ruby-gem", + "ruby-plain", + "rust-cargo", + "rust-plain", + "ts-plain", + ]; + await Promise.all(allVariants.map((variant) => testKind(variant))); + + return true; +}); + +export const testKind = tg.target(async (kind: Kind) => { + await testDetectKind(kind); + // await testBuildKind(kind); + return true; +}); + +export const testDetectKind = tg.target(async (kind: Kind) => { + const source = await tests.get(kind).then(tg.Directory.expect); + const detectedKind = await detectKind(source); + tg.assert(detectedKind === kind, `expected ${kind}, got ${detectedKind}`); + return true; +}); + +// export const testBuildKind = tg.target(async (kind: Kind, outputTestFn?: (output: tg.Directory) => Promise) => { +// const source = await tests.get(kind).then(tg.Directory.expect); +// const buildOutput = await default_({ source }).then(tg.Directory.expect); +// const outputTestFn_ = outputTestFn ?? async (output: tg.Directory) => { +// const expected = "Hello, world!"; +// const actual = await $`${output}/bin/test > $OUTPUT`.then(tg.File.expect).then((t) => t.text()).then((t) => t.trim()); +// tg.assert(expected === actual); +// return true; +// }; +// await outputTestFn_(buildOutput); +// return true; +// }); + +type WrapScriptsArg = std.wrap.ArgObject & { + directory: tg.Directory; + extension: string; +}; + +/** Wrap all the scripts with a given extension to use the given interpreter */ +const wrapScripts = async (arg: WrapScriptsArg): Promise => { + const { directory, extension, ...wrapArg } = arg; + let ret = arg.directory; + for await (const [name, artifact] of arg.directory) { + if (name.endsWith(extension) && artifact instanceof tg.File) { + ret = await tg.directory(ret, { + [`${name}`]: std.wrap(artifact, wrapArg), + }); + } + } + return ret; +}; + +/** We need to generate the distribution bundle for the `cc-autotools` test package, generating the configure scripts and intermediate makefile templates. */ +// FIXME - this fails!! autreconf is not able to run. +export const prepareAutotoolsTestDistributionBundle = tg.target(async () => { + const originalSource = await tests + .get("cc-autotools") + .then(tg.Directory.expect); + return $`set -eux && cp -R ${originalSource} $OUTPUT && chmod -R u+w $OUTPUT && cd $OUTPUT && env && which autoconf && autoreconf --install` + .env(autoconf(), automake()) + .then(tg.Directory.expect); +}); diff --git a/packages/autobuild/tests/c-plain/main.c b/packages/autobuild/tests/c-plain/main.c new file mode 100644 index 00000000..632a8045 --- /dev/null +++ b/packages/autobuild/tests/c-plain/main.c @@ -0,0 +1,7 @@ +#include +#include + +int main() { + printf("Hello, world!\n"); + return EXIT_SUCCESS; +} diff --git a/packages/autobuild/tests/cc-autotools/Makefile.am b/packages/autobuild/tests/cc-autotools/Makefile.am new file mode 100644 index 00000000..38bdf12e --- /dev/null +++ b/packages/autobuild/tests/cc-autotools/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = src +dist_doc_DATA = README diff --git a/packages/autobuild/tests/cc-autotools/README b/packages/autobuild/tests/cc-autotools/README new file mode 100644 index 00000000..28fa1fb9 --- /dev/null +++ b/packages/autobuild/tests/cc-autotools/README @@ -0,0 +1 @@ +example autotools package diff --git a/packages/autobuild/tests/cc-autotools/configure.ac b/packages/autobuild/tests/cc-autotools/configure.ac new file mode 100644 index 00000000..4b5bb541 --- /dev/null +++ b/packages/autobuild/tests/cc-autotools/configure.ac @@ -0,0 +1,9 @@ +AC_INIT([amhello], [1.0], [hello@tangram.dev]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +AC_PROG_CC +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES([ + Makefile + src/Makefile +]) +AC_OUTPUT diff --git a/packages/autobuild/tests/cc-autotools/src/Makefile.am b/packages/autobuild/tests/cc-autotools/src/Makefile.am new file mode 100644 index 00000000..0552a007 --- /dev/null +++ b/packages/autobuild/tests/cc-autotools/src/Makefile.am @@ -0,0 +1,2 @@ +bin_PROGRAMS = hello +hello_SOURCES = main.c diff --git a/packages/autobuild/tests/cc-autotools/src/main.c b/packages/autobuild/tests/cc-autotools/src/main.c new file mode 100644 index 00000000..632a8045 --- /dev/null +++ b/packages/autobuild/tests/cc-autotools/src/main.c @@ -0,0 +1,7 @@ +#include +#include + +int main() { + printf("Hello, world!\n"); + return EXIT_SUCCESS; +} diff --git a/packages/autobuild/tests/cmake/CMakeLists.txt b/packages/autobuild/tests/cmake/CMakeLists.txt new file mode 100644 index 00000000..0f10784e --- /dev/null +++ b/packages/autobuild/tests/cmake/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.10) +project(DemoProject VERSION 1.0) + +# Specify C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Add executable +add_executable(demo_app src/main.cpp) diff --git a/packages/autobuild/tests/cmake/src/main.cpp b/packages/autobuild/tests/cmake/src/main.cpp new file mode 100644 index 00000000..8a2c4e27 --- /dev/null +++ b/packages/autobuild/tests/cmake/src/main.cpp @@ -0,0 +1,7 @@ +#include +#include + +int main() { + std::cout << "Hello, world!\n"; + return EXIT_SUCCESS; +} diff --git a/packages/autobuild/tests/cxx-plain/main.cxx b/packages/autobuild/tests/cxx-plain/main.cxx new file mode 100644 index 00000000..bac63572 --- /dev/null +++ b/packages/autobuild/tests/cxx-plain/main.cxx @@ -0,0 +1,7 @@ +#include +#include + +int main() { + std::cout << "Hello, world!" << std::endl; + return EXIT_SUCCESS; +} diff --git a/packages/autobuild/tests/fortran-plain/main.f90 b/packages/autobuild/tests/fortran-plain/main.f90 new file mode 100644 index 00000000..ee7dacf4 --- /dev/null +++ b/packages/autobuild/tests/fortran-plain/main.f90 @@ -0,0 +1,3 @@ +program hello + print *, "Hello, World!" +end program hello diff --git a/packages/autobuild/tests/go/go.mod b/packages/autobuild/tests/go/go.mod new file mode 100644 index 00000000..2f4fe910 --- /dev/null +++ b/packages/autobuild/tests/go/go.mod @@ -0,0 +1,3 @@ +module hello + +go 1.23.3 diff --git a/packages/autobuild/tests/go/hello.go b/packages/autobuild/tests/go/hello.go new file mode 100644 index 00000000..b7d2a320 --- /dev/null +++ b/packages/autobuild/tests/go/hello.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello, World!") +} diff --git a/packages/autobuild/tests/js-node/main.js b/packages/autobuild/tests/js-node/main.js new file mode 100644 index 00000000..f4e18b07 --- /dev/null +++ b/packages/autobuild/tests/js-node/main.js @@ -0,0 +1,2 @@ +const GREETING = "Hello, world!"; +console.log(GREETING); diff --git a/packages/autobuild/tests/js-node/package.json b/packages/autobuild/tests/js-node/package.json new file mode 100644 index 00000000..d819b571 --- /dev/null +++ b/packages/autobuild/tests/js-node/package.json @@ -0,0 +1,9 @@ +{ + "name": "demo-nodejs-project", + "version": "1.0.0", + "description": "A basic Node.js project that displays text to stdout", + "main": "index.js", + "scripts": { + "start": "node index.js" + } +} diff --git a/packages/autobuild/tests/js-plain/index.js b/packages/autobuild/tests/js-plain/index.js new file mode 100644 index 00000000..f4e18b07 --- /dev/null +++ b/packages/autobuild/tests/js-plain/index.js @@ -0,0 +1,2 @@ +const GREETING = "Hello, world!"; +console.log(GREETING); 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-poetry/README.md b/packages/autobuild/tests/python-poetry/README.md new file mode 100644 index 00000000..c000e1c5 --- /dev/null +++ b/packages/autobuild/tests/python-poetry/README.md @@ -0,0 +1,3 @@ +# demo + +A sample Poetry package. diff --git a/packages/autobuild/tests/python-poetry/pyproject.toml b/packages/autobuild/tests/python-poetry/pyproject.toml new file mode 100644 index 00000000..be1a009d --- /dev/null +++ b/packages/autobuild/tests/python-poetry/pyproject.toml @@ -0,0 +1,20 @@ +[tool.poetry] +name = "demo-package" +version = "0.1.0" +description = "A demonstration package that displays text to stdout" +authors = ["Tangram "] +readme = "README.md" +packages = [{include = "demo_package", from = "src"}] + +[tool.poetry.dependencies] +python = "^3.8" + +[tool.poetry.group.dev.dependencies] +pytest = "^7.0" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +demo-text = "demo_package.main:main" diff --git a/packages/autobuild/tests/python-poetry/src/demo_package/__init__.py b/packages/autobuild/tests/python-poetry/src/demo_package/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/packages/autobuild/tests/python-poetry/src/demo_package/main.py b/packages/autobuild/tests/python-poetry/src/demo_package/main.py new file mode 100644 index 00000000..4dcbe93c --- /dev/null +++ b/packages/autobuild/tests/python-poetry/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-poetry/tests/__init__.py b/packages/autobuild/tests/python-poetry/tests/__init__.py new file mode 100644 index 00000000..e69de29b 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..99d4c4ea --- /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] +demo-text = "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..4dcbe93c --- /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/ruby-gem/.gitignore b/packages/autobuild/tests/ruby-gem/.gitignore new file mode 100644 index 00000000..9106b2a3 --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/.gitignore @@ -0,0 +1,8 @@ +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ diff --git a/packages/autobuild/tests/ruby-gem/Gemfile b/packages/autobuild/tests/ruby-gem/Gemfile new file mode 100644 index 00000000..f6359393 --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } + +# Specify your gem's dependencies in ruby-gem.gemspec +gemspec diff --git a/packages/autobuild/tests/ruby-gem/README.md b/packages/autobuild/tests/ruby-gem/README.md new file mode 100644 index 00000000..ee340b53 --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/README.md @@ -0,0 +1,35 @@ +# Ruby::Gem + +Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ruby/gem`. To experiment with that code, run `bin/console` for an interactive prompt. + +TODO: Delete this and the text above, and describe your gem + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'ruby-gem' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install ruby-gem + +## Usage + +TODO: Write usage instructions here + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ruby-gem. diff --git a/packages/autobuild/tests/ruby-gem/Rakefile b/packages/autobuild/tests/ruby-gem/Rakefile new file mode 100644 index 00000000..43022f71 --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/Rakefile @@ -0,0 +1,2 @@ +require "bundler/gem_tasks" +task :default => :spec diff --git a/packages/autobuild/tests/ruby-gem/bin/console b/packages/autobuild/tests/ruby-gem/bin/console new file mode 100755 index 00000000..7f621f21 --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/bin/console @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "ruby/gem" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start(__FILE__) diff --git a/packages/autobuild/tests/ruby-gem/bin/setup b/packages/autobuild/tests/ruby-gem/bin/setup new file mode 100755 index 00000000..dce67d86 --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/packages/autobuild/tests/ruby-gem/lib/ruby/gem.rb b/packages/autobuild/tests/ruby-gem/lib/ruby/gem.rb new file mode 100644 index 00000000..17afe9a6 --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/lib/ruby/gem.rb @@ -0,0 +1,8 @@ +require "ruby/gem/version" + +module Ruby + module Gem + class Error < StandardError; end + # Your code goes here... + end +end diff --git a/packages/autobuild/tests/ruby-gem/lib/ruby/gem/version.rb b/packages/autobuild/tests/ruby-gem/lib/ruby/gem/version.rb new file mode 100644 index 00000000..9c07dc8d --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/lib/ruby/gem/version.rb @@ -0,0 +1,5 @@ +module Ruby + module Gem + VERSION = "0.1.0" + end +end diff --git a/packages/autobuild/tests/ruby-gem/ruby-gem.gemspec b/packages/autobuild/tests/ruby-gem/ruby-gem.gemspec new file mode 100644 index 00000000..deaa6258 --- /dev/null +++ b/packages/autobuild/tests/ruby-gem/ruby-gem.gemspec @@ -0,0 +1,40 @@ + +lib = File.expand_path("../lib", __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "ruby/gem/version" + +Gem::Specification.new do |spec| + spec.name = "ruby-gem" + spec.version = Ruby::Gem::VERSION + spec.authors = ["Ben Lovy"] + spec.email = ["ben@deciduously.com"] + + spec.summary = %q{TODO: Write a short summary, because RubyGems requires one.} + spec.description = %q{TODO: Write a longer description or delete this line.} + spec.homepage = "TODO: Put your gem's website or public repo URL here." + + # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' + # to allow pushing to a single host or delete this section to allow pushing to any host. + if spec.respond_to?(:metadata) + spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'" + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here." + spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." + else + raise "RubyGems 2.0 or newer is required to protect against " \ + "public gem pushes." + end + + # Specify which files should be added to the gem when it is released. + # The `git ls-files -z` loads the files in the RubyGem that have been added into git. + spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do + `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + end + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] + + spec.add_development_dependency "bundler", "~> 1.17" + spec.add_development_dependency "rake", "~> 10.0" +end diff --git a/packages/autobuild/tests/ruby-plain/main.rb b/packages/autobuild/tests/ruby-plain/main.rb new file mode 100644 index 00000000..bf234ce7 --- /dev/null +++ b/packages/autobuild/tests/ruby-plain/main.rb @@ -0,0 +1 @@ +puts "Hello, world!" diff --git a/packages/autobuild/tests/rust-cargo/Cargo.lock b/packages/autobuild/tests/rust-cargo/Cargo.lock new file mode 100644 index 00000000..6a825f5e --- /dev/null +++ b/packages/autobuild/tests/rust-cargo/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "rust-cargo" +version = "0.1.0" diff --git a/packages/autobuild/tests/rust-cargo/Cargo.toml b/packages/autobuild/tests/rust-cargo/Cargo.toml new file mode 100644 index 00000000..a691f668 --- /dev/null +++ b/packages/autobuild/tests/rust-cargo/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rust-cargo" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/packages/autobuild/tests/rust-cargo/src/main.rs b/packages/autobuild/tests/rust-cargo/src/main.rs new file mode 100644 index 00000000..e7a11a96 --- /dev/null +++ b/packages/autobuild/tests/rust-cargo/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} 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/autobuild/tests/ts-plain/main.ts b/packages/autobuild/tests/ts-plain/main.ts new file mode 100644 index 00000000..962cd2a4 --- /dev/null +++ b/packages/autobuild/tests/ts-plain/main.ts @@ -0,0 +1,2 @@ +const GREETING: string = "Hello, world!"; +console.log(GREETING); diff --git a/packages/autobuild/ts/tangram.ts b/packages/autobuild/ts/tangram.ts new file mode 100644 index 00000000..06f52f63 --- /dev/null +++ b/packages/autobuild/ts/tangram.ts @@ -0,0 +1,18 @@ +import * as std from "std" with { path: "../../std" }; + +export type Arg = { + build?: string; + env?: std.env.Arg; + host?: string; + source: tg.Directory; +}; + +export const default_ = tg.target(async (arg: Arg) => { + return tg.unimplemented(); +}); + +export default default_; + +export const test = tg.target(async () => { + return tg.unimplemented(); +});