Skip to content

Commit

Permalink
fix(run): interpret extensionless files as typescript (#5711)
Browse files Browse the repository at this point in the history
* test

* gadsgsagdsa

* add better err msg

* r

* oops

* ok
  • Loading branch information
paperclover authored Sep 21, 2023
1 parent b65862e commit b795151
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 19 deletions.
4 changes: 4 additions & 0 deletions packages/bun-types/bun.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ declare module "bun" {
export function write(
destination: BunFile | PathLike,
input: Blob | TypedArray | ArrayBufferLike | string | BlobPart[],
options?: {
/** If writing to a PathLike, set the permissions of the file. */
mode?: number;
},
): Promise<number>;

/**
Expand Down
4 changes: 2 additions & 2 deletions src/bun.js/bindings/JSBuffer.lut.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ static const struct CompactHashIndex jsBufferConstructorTableIndex[33] = {

static const struct HashTableValue jsBufferConstructorTableValues[10] = {
{ "alloc"_s, static_cast<unsigned>(PropertyAttribute::Constructable|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_alloc, 1 } },
{ "allocUnsafe"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafe, 1 } },
{ "allocUnsafeSlow"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafeSlow, 1 } },
{ "allocUnsafe"_s, static_cast<unsigned>(PropertyAttribute::Constructable|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafe, 1 } },
{ "allocUnsafeSlow"_s, static_cast<unsigned>(PropertyAttribute::Constructable|PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_allocUnsafeSlow, 1 } },
{ "byteLength"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_byteLength, 2 } },
{ "compare"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_compare, 2 } },
{ "concat"_s, static_cast<unsigned>(PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBufferConstructorFunction_concat, 2 } },
Expand Down
23 changes: 15 additions & 8 deletions src/bun.js/module_loader.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1937,14 +1937,21 @@ pub const ModuleLoader = struct {
}
}

const synchronous_loader = loader orelse
// Unknown extensions are to be treated as file loader
if (jsc_vm.has_loaded or jsc_vm.is_in_preload)
options.Loader.file
else
// Unless it's potentially the main module
// This is important so that "bun run ./foo-i-have-no-extension" works
options.Loader.js;
const synchronous_loader = loader orelse loader: {
if (jsc_vm.has_loaded or jsc_vm.is_in_preload) {
// Extensionless files in this context are treated as the JS loader
if (path.name.ext.len == 0) {
break :loader options.Loader.tsx;
}

// Unknown extensions are to be treated as file loader
break :loader options.Loader.file;
} else {
// Unless it's potentially the main module
// This is important so that "bun run ./foo-i-have-no-extension" works
break :loader options.Loader.tsx;
}
};

var promise: ?*JSC.JSInternalPromise = null;
ret.* = ErrorableResolvedSource.ok(
Expand Down
9 changes: 6 additions & 3 deletions src/fs.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1338,8 +1338,10 @@ pub const PathName = struct {
base: string,
dir: string,
/// includes the leading .
/// extensionless files report ""
ext: string,
filename: string,

pub fn nonUniqueNameStringBase(self: *const PathName) string {
// /bar/foo/index.js -> foo
if (self.dir.len > 0 and strings.eqlComptime(self.base, "index")) {
Expand Down Expand Up @@ -1398,7 +1400,7 @@ pub const PathName = struct {
pub fn init(_path: string) PathName {
var path = _path;
var base = path;
var ext = path;
var ext: []const u8 = undefined;
var dir = path;
var is_absolute = true;

Expand All @@ -1419,10 +1421,11 @@ pub const PathName = struct {
}

// Strip off the extension
var _dot = strings.lastIndexOfChar(base, '.');
if (_dot) |dot| {
if (strings.lastIndexOfChar(base, '.')) |dot| {
ext = base[dot..];
base = base[0..dot];
} else {
ext = "";
}

if (is_absolute) {
Expand Down
2 changes: 1 addition & 1 deletion src/js/node/child_process.js
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ function nodeToBun(item) {
return item;
} else {
const result = nodeToBunLookup[item];
if (result === undefined) throw new Error("Invalid stdio option");
if (result === undefined) throw new Error(`Invalid stdio option "${item}"`);
return result;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/js/out/InternalModuleRegistryConstants.h

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bun.write("/tmp/bun-write-permission-test.txt", "test", { mode: 0o777 });
Binary file modified test/bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion test/cli/run/run-cjs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { bunEnv, bunExe } from "harness";
import { tmpdir } from "os";
import { join } from "path";

test.todo("running a commonjs module works", async () => {
test("running a commonjs module works", async () => {
const dir = join(realpathSync(tmpdir()), "bun-run-test1");
mkdirSync(dir, { recursive: true });
await Bun.write(join(dir, "index1.js"), "module.exports = 1; console.log('hello world');");
Expand Down
31 changes: 31 additions & 0 deletions test/cli/run/run-extensionless.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { expect, test } from "bun:test";
import { mkdirSync, realpathSync } from "fs";
import { bunEnv, bunExe } from "harness";
import { writeFileSync } from "fs";
import { tmpdir } from "os";
import { join } from "path";

test("running extensionless file works", async () => {
const dir = join(realpathSync(tmpdir()), "bun-run-test1");
mkdirSync(dir, { recursive: true });
await Bun.write(join(dir, "cool"), "const x: Test = 2; console.log('hello world');");
let { stdout } = Bun.spawnSync({
cmd: [bunExe(), join(dir, "./cool")],
cwd: dir,
env: bunEnv,
});
expect(stdout.toString("utf8")).toEqual("hello world\n");
});

test("running shebang typescript file works", async () => {
const dir = join(realpathSync(tmpdir()), "bun-run-test2");
mkdirSync(dir, { recursive: true });
writeFileSync(join(dir, "cool"), `#!${bunExe()}\nconst x: Test = 2; console.log('hello world');`, { mode: 0o777 });

let { stdout } = Bun.spawnSync({
cmd: [join(dir, "./cool")],
cwd: dir,
env: bunEnv,
});
expect(stdout.toString("utf8")).toEqual("hello world\n");
});
7 changes: 7 additions & 0 deletions test/js/third_party/yargs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "yargs-test",
"version": "1.0.0",
"dependencies": {
"yargs": "17.7.2"
}
}
4 changes: 4 additions & 0 deletions test/js/third_party/yargs/yargs-cjs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
test("yargs/yargs works", () => {
const yargs = require("yargs/yargs");
expect(yargs).toBeFunction();
});
2 changes: 1 addition & 1 deletion test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"vitest": "0.32.2",
"webpack": "5.88.0",
"webpack-cli": "4.7.2",
"mongodb": "6.0.0"
"yargs": "17.7.2"
},
"private": true,
"scripts": {
Expand Down

0 comments on commit b795151

Please sign in to comment.