mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
[bun install] Implement bunfig.toml config
This commit is contained in:
Binary file not shown.
Binary file not shown.
48
src/api/schema.d.ts
generated
vendored
48
src/api/schema.d.ts
generated
vendored
@@ -603,6 +603,37 @@ export interface WebsocketMessageResolveID {
|
||||
id: uint32;
|
||||
}
|
||||
|
||||
export interface NPMRegistry {
|
||||
url: string;
|
||||
username: string;
|
||||
password: string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface NPMRegistryMap {
|
||||
scopes: string[];
|
||||
registries: NPMRegistry[];
|
||||
}
|
||||
|
||||
export interface BunInstall {
|
||||
default_registry?: NPMRegistry;
|
||||
scoped?: NPMRegistryMap;
|
||||
lockfile_path?: string;
|
||||
save_lockfile_path?: string;
|
||||
cache_directory?: string;
|
||||
dry_run?: boolean;
|
||||
force?: boolean;
|
||||
save_dev?: boolean;
|
||||
save_optional?: boolean;
|
||||
save_peer?: boolean;
|
||||
save_lockfile?: boolean;
|
||||
production?: boolean;
|
||||
save_yarn_lockfile?: boolean;
|
||||
native_bin_links?: string[];
|
||||
disable_cache?: boolean;
|
||||
disable_manifest_cache?: boolean;
|
||||
}
|
||||
|
||||
export declare function encodeStackFrame(
|
||||
message: StackFrame,
|
||||
bb: ByteBuffer
|
||||
@@ -869,3 +900,20 @@ export declare function encodeWebsocketMessageResolveID(
|
||||
export declare function decodeWebsocketMessageResolveID(
|
||||
buffer: ByteBuffer
|
||||
): WebsocketMessageResolveID;
|
||||
export declare function encodeNPMRegistry(
|
||||
message: NPMRegistry,
|
||||
bb: ByteBuffer
|
||||
): void;
|
||||
export declare function decodeNPMRegistry(buffer: ByteBuffer): NPMRegistry;
|
||||
export declare function encodeNPMRegistryMap(
|
||||
message: NPMRegistryMap,
|
||||
bb: ByteBuffer
|
||||
): void;
|
||||
export declare function decodeNPMRegistryMap(
|
||||
buffer: ByteBuffer
|
||||
): NPMRegistryMap;
|
||||
export declare function encodeBunInstall(
|
||||
message: BunInstall,
|
||||
bb: ByteBuffer
|
||||
): void;
|
||||
export declare function decodeBunInstall(buffer: ByteBuffer): BunInstall;
|
||||
|
||||
271
src/api/schema.js
generated
271
src/api/schema.js
generated
@@ -2748,6 +2748,271 @@ function encodeWebsocketMessageResolveID(message, bb) {
|
||||
}
|
||||
}
|
||||
|
||||
function decodeNPMRegistry(bb) {
|
||||
var result = {};
|
||||
|
||||
result["url"] = bb.readString();
|
||||
result["username"] = bb.readString();
|
||||
result["password"] = bb.readString();
|
||||
result["token"] = bb.readString();
|
||||
return result;
|
||||
}
|
||||
|
||||
function encodeNPMRegistry(message, bb) {
|
||||
var value = message["url"];
|
||||
if (value != null) {
|
||||
bb.writeString(value);
|
||||
} else {
|
||||
throw new Error('Missing required field "url"');
|
||||
}
|
||||
|
||||
var value = message["username"];
|
||||
if (value != null) {
|
||||
bb.writeString(value);
|
||||
} else {
|
||||
throw new Error('Missing required field "username"');
|
||||
}
|
||||
|
||||
var value = message["password"];
|
||||
if (value != null) {
|
||||
bb.writeString(value);
|
||||
} else {
|
||||
throw new Error('Missing required field "password"');
|
||||
}
|
||||
|
||||
var value = message["token"];
|
||||
if (value != null) {
|
||||
bb.writeString(value);
|
||||
} else {
|
||||
throw new Error('Missing required field "token"');
|
||||
}
|
||||
}
|
||||
|
||||
function decodeNPMRegistryMap(bb) {
|
||||
var result = {};
|
||||
|
||||
var length = bb.readVarUint();
|
||||
var values = (result["scopes"] = Array(length));
|
||||
for (var i = 0; i < length; i++) values[i] = bb.readString();
|
||||
var length = bb.readVarUint();
|
||||
var values = (result["registries"] = Array(length));
|
||||
for (var i = 0; i < length; i++) values[i] = decodeNPMRegistry(bb);
|
||||
return result;
|
||||
}
|
||||
|
||||
function encodeNPMRegistryMap(message, bb) {
|
||||
var value = message["scopes"];
|
||||
if (value != null) {
|
||||
var values = value,
|
||||
n = values.length;
|
||||
bb.writeVarUint(n);
|
||||
for (var i = 0; i < n; i++) {
|
||||
value = values[i];
|
||||
bb.writeString(value);
|
||||
}
|
||||
} else {
|
||||
throw new Error('Missing required field "scopes"');
|
||||
}
|
||||
|
||||
var value = message["registries"];
|
||||
if (value != null) {
|
||||
var values = value,
|
||||
n = values.length;
|
||||
bb.writeVarUint(n);
|
||||
for (var i = 0; i < n; i++) {
|
||||
value = values[i];
|
||||
encodeNPMRegistry(value, bb);
|
||||
}
|
||||
} else {
|
||||
throw new Error('Missing required field "registries"');
|
||||
}
|
||||
}
|
||||
|
||||
function decodeBunInstall(bb) {
|
||||
var result = {};
|
||||
|
||||
while (true) {
|
||||
switch (bb.readByte()) {
|
||||
case 0:
|
||||
return result;
|
||||
|
||||
case 1:
|
||||
result["default_registry"] = decodeNPMRegistry(bb);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
result["scoped"] = decodeNPMRegistryMap(bb);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
result["lockfile_path"] = bb.readString();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
result["save_lockfile_path"] = bb.readString();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
result["cache_directory"] = bb.readString();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
result["dry_run"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 7:
|
||||
result["force"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
result["save_dev"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 9:
|
||||
result["save_optional"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 10:
|
||||
result["save_peer"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 11:
|
||||
result["save_lockfile"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 12:
|
||||
result["production"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 13:
|
||||
result["save_yarn_lockfile"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 14:
|
||||
var length = bb.readVarUint();
|
||||
var values = (result["native_bin_links"] = Array(length));
|
||||
for (var i = 0; i < length; i++) values[i] = bb.readString();
|
||||
break;
|
||||
|
||||
case 15:
|
||||
result["disable_cache"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 16:
|
||||
result["disable_manifest_cache"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Attempted to parse invalid message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function encodeBunInstall(message, bb) {
|
||||
var value = message["default_registry"];
|
||||
if (value != null) {
|
||||
bb.writeByte(1);
|
||||
encodeNPMRegistry(value, bb);
|
||||
}
|
||||
|
||||
var value = message["scoped"];
|
||||
if (value != null) {
|
||||
bb.writeByte(2);
|
||||
encodeNPMRegistryMap(value, bb);
|
||||
}
|
||||
|
||||
var value = message["lockfile_path"];
|
||||
if (value != null) {
|
||||
bb.writeByte(3);
|
||||
bb.writeString(value);
|
||||
}
|
||||
|
||||
var value = message["save_lockfile_path"];
|
||||
if (value != null) {
|
||||
bb.writeByte(4);
|
||||
bb.writeString(value);
|
||||
}
|
||||
|
||||
var value = message["cache_directory"];
|
||||
if (value != null) {
|
||||
bb.writeByte(5);
|
||||
bb.writeString(value);
|
||||
}
|
||||
|
||||
var value = message["dry_run"];
|
||||
if (value != null) {
|
||||
bb.writeByte(6);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["force"];
|
||||
if (value != null) {
|
||||
bb.writeByte(7);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["save_dev"];
|
||||
if (value != null) {
|
||||
bb.writeByte(8);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["save_optional"];
|
||||
if (value != null) {
|
||||
bb.writeByte(9);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["save_peer"];
|
||||
if (value != null) {
|
||||
bb.writeByte(10);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["save_lockfile"];
|
||||
if (value != null) {
|
||||
bb.writeByte(11);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["production"];
|
||||
if (value != null) {
|
||||
bb.writeByte(12);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["save_yarn_lockfile"];
|
||||
if (value != null) {
|
||||
bb.writeByte(13);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["native_bin_links"];
|
||||
if (value != null) {
|
||||
bb.writeByte(14);
|
||||
var values = value,
|
||||
n = values.length;
|
||||
bb.writeVarUint(n);
|
||||
for (var i = 0; i < n; i++) {
|
||||
value = values[i];
|
||||
bb.writeString(value);
|
||||
}
|
||||
}
|
||||
|
||||
var value = message["disable_cache"];
|
||||
if (value != null) {
|
||||
bb.writeByte(15);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["disable_manifest_cache"];
|
||||
if (value != null) {
|
||||
bb.writeByte(16);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
bb.writeByte(0);
|
||||
}
|
||||
|
||||
export { Loader };
|
||||
export { LoaderKeys };
|
||||
export { FrameworkEntryPointType };
|
||||
@@ -2874,3 +3139,9 @@ export { decodeWebsocketCommandBuildWithFilePath };
|
||||
export { encodeWebsocketCommandBuildWithFilePath };
|
||||
export { decodeWebsocketMessageResolveID };
|
||||
export { encodeWebsocketMessageResolveID };
|
||||
export { decodeNPMRegistry };
|
||||
export { encodeNPMRegistry };
|
||||
export { decodeNPMRegistryMap };
|
||||
export { encodeNPMRegistryMap };
|
||||
export { decodeBunInstall };
|
||||
export { encodeBunInstall };
|
||||
|
||||
@@ -344,7 +344,6 @@ message TransformOptions {
|
||||
|
||||
uint16 port = 25;
|
||||
MessageLevel logLevel = 26;
|
||||
|
||||
}
|
||||
|
||||
struct FileHandle {
|
||||
@@ -516,4 +515,36 @@ struct WebsocketCommandBuildWithFilePath {
|
||||
|
||||
struct WebsocketMessageResolveID {
|
||||
uint32 id;
|
||||
}
|
||||
|
||||
struct NPMRegistry {
|
||||
string url;
|
||||
string username;
|
||||
string password;
|
||||
string token;
|
||||
}
|
||||
|
||||
struct NPMRegistryMap {
|
||||
string[] scopes;
|
||||
NPMRegistry[] registries;
|
||||
}
|
||||
|
||||
message BunInstall {
|
||||
NPMRegistry default_registry = 1;
|
||||
NPMRegistryMap scoped = 2;
|
||||
string lockfile_path = 3;
|
||||
string save_lockfile_path = 4;
|
||||
string cache_directory = 5;
|
||||
bool dry_run = 6;
|
||||
bool force = 7;
|
||||
bool save_dev = 8;
|
||||
bool save_optional = 9;
|
||||
bool save_peer = 10;
|
||||
bool save_lockfile = 11;
|
||||
bool production = 12;
|
||||
bool save_yarn_lockfile = 13;
|
||||
string[] native_bin_links = 14;
|
||||
|
||||
bool disable_cache = 15;
|
||||
bool disable_manifest_cache = 16;
|
||||
}
|
||||
@@ -2617,4 +2617,239 @@ pub const Api = struct {
|
||||
try writer.writeInt(this.id);
|
||||
}
|
||||
};
|
||||
|
||||
pub const NpmRegistry = struct {
|
||||
/// url
|
||||
url: []const u8,
|
||||
|
||||
/// username
|
||||
username: []const u8,
|
||||
|
||||
/// password
|
||||
password: []const u8,
|
||||
|
||||
/// token
|
||||
token: []const u8,
|
||||
|
||||
pub fn decode(reader: anytype) anyerror!NpmRegistry {
|
||||
var this = std.mem.zeroes(NpmRegistry);
|
||||
|
||||
this.url = try reader.readValue([]const u8);
|
||||
this.username = try reader.readValue([]const u8);
|
||||
this.password = try reader.readValue([]const u8);
|
||||
this.token = try reader.readValue([]const u8);
|
||||
return this;
|
||||
}
|
||||
|
||||
pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
|
||||
try writer.writeValue(@TypeOf(this.url), this.url);
|
||||
try writer.writeValue(@TypeOf(this.username), this.username);
|
||||
try writer.writeValue(@TypeOf(this.password), this.password);
|
||||
try writer.writeValue(@TypeOf(this.token), this.token);
|
||||
}
|
||||
};
|
||||
|
||||
pub const NpmRegistryMap = struct {
|
||||
/// scopes
|
||||
scopes: []const []const u8,
|
||||
|
||||
/// registries
|
||||
registries: []const NpmRegistry,
|
||||
|
||||
pub fn decode(reader: anytype) anyerror!NpmRegistryMap {
|
||||
var this = std.mem.zeroes(NpmRegistryMap);
|
||||
|
||||
this.scopes = try reader.readArray([]const u8);
|
||||
this.registries = try reader.readArray(NpmRegistry);
|
||||
return this;
|
||||
}
|
||||
|
||||
pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
|
||||
try writer.writeArray([]const u8, this.scopes);
|
||||
try writer.writeArray(NpmRegistry, this.registries);
|
||||
}
|
||||
};
|
||||
|
||||
pub const BunInstall = struct {
|
||||
/// default_registry
|
||||
default_registry: ?NpmRegistry = null,
|
||||
|
||||
/// scoped
|
||||
scoped: ?NpmRegistryMap = null,
|
||||
|
||||
/// lockfile_path
|
||||
lockfile_path: ?[]const u8 = null,
|
||||
|
||||
/// save_lockfile_path
|
||||
save_lockfile_path: ?[]const u8 = null,
|
||||
|
||||
/// cache_directory
|
||||
cache_directory: ?[]const u8 = null,
|
||||
|
||||
/// dry_run
|
||||
dry_run: ?bool = null,
|
||||
|
||||
/// force
|
||||
force: ?bool = null,
|
||||
|
||||
/// save_dev
|
||||
save_dev: ?bool = null,
|
||||
|
||||
/// save_optional
|
||||
save_optional: ?bool = null,
|
||||
|
||||
/// save_peer
|
||||
save_peer: ?bool = null,
|
||||
|
||||
/// save_lockfile
|
||||
save_lockfile: ?bool = null,
|
||||
|
||||
/// production
|
||||
production: ?bool = null,
|
||||
|
||||
/// save_yarn_lockfile
|
||||
save_yarn_lockfile: ?bool = null,
|
||||
|
||||
/// native_bin_links
|
||||
native_bin_links: []const []const u8,
|
||||
|
||||
/// disable_cache
|
||||
disable_cache: ?bool = null,
|
||||
|
||||
/// disable_manifest_cache
|
||||
disable_manifest_cache: ?bool = null,
|
||||
|
||||
pub fn decode(reader: anytype) anyerror!BunInstall {
|
||||
var this = std.mem.zeroes(BunInstall);
|
||||
|
||||
while (true) {
|
||||
switch (try reader.readByte()) {
|
||||
0 => {
|
||||
return this;
|
||||
},
|
||||
|
||||
1 => {
|
||||
this.default_registry = try reader.readValue(NpmRegistry);
|
||||
},
|
||||
2 => {
|
||||
this.scoped = try reader.readValue(NpmRegistryMap);
|
||||
},
|
||||
3 => {
|
||||
this.lockfile_path = try reader.readValue([]const u8);
|
||||
},
|
||||
4 => {
|
||||
this.save_lockfile_path = try reader.readValue([]const u8);
|
||||
},
|
||||
5 => {
|
||||
this.cache_directory = try reader.readValue([]const u8);
|
||||
},
|
||||
6 => {
|
||||
this.dry_run = try reader.readValue(bool);
|
||||
},
|
||||
7 => {
|
||||
this.force = try reader.readValue(bool);
|
||||
},
|
||||
8 => {
|
||||
this.save_dev = try reader.readValue(bool);
|
||||
},
|
||||
9 => {
|
||||
this.save_optional = try reader.readValue(bool);
|
||||
},
|
||||
10 => {
|
||||
this.save_peer = try reader.readValue(bool);
|
||||
},
|
||||
11 => {
|
||||
this.save_lockfile = try reader.readValue(bool);
|
||||
},
|
||||
12 => {
|
||||
this.production = try reader.readValue(bool);
|
||||
},
|
||||
13 => {
|
||||
this.save_yarn_lockfile = try reader.readValue(bool);
|
||||
},
|
||||
14 => {
|
||||
this.native_bin_links = try reader.readArray([]const u8);
|
||||
},
|
||||
15 => {
|
||||
this.disable_cache = try reader.readValue(bool);
|
||||
},
|
||||
16 => {
|
||||
this.disable_manifest_cache = try reader.readValue(bool);
|
||||
},
|
||||
else => {
|
||||
return error.InvalidMessage;
|
||||
},
|
||||
}
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
pub fn encode(this: *const @This(), writer: anytype) anyerror!void {
|
||||
if (this.default_registry) |default_registry| {
|
||||
try writer.writeFieldID(1);
|
||||
try writer.writeValue(@TypeOf(default_registry), default_registry);
|
||||
}
|
||||
if (this.scoped) |scoped| {
|
||||
try writer.writeFieldID(2);
|
||||
try writer.writeValue(@TypeOf(scoped), scoped);
|
||||
}
|
||||
if (this.lockfile_path) |lockfile_path| {
|
||||
try writer.writeFieldID(3);
|
||||
try writer.writeValue(@TypeOf(lockfile_path), lockfile_path);
|
||||
}
|
||||
if (this.save_lockfile_path) |save_lockfile_path| {
|
||||
try writer.writeFieldID(4);
|
||||
try writer.writeValue(@TypeOf(save_lockfile_path), save_lockfile_path);
|
||||
}
|
||||
if (this.cache_directory) |cache_directory| {
|
||||
try writer.writeFieldID(5);
|
||||
try writer.writeValue(@TypeOf(cache_directory), cache_directory);
|
||||
}
|
||||
if (this.dry_run) |dry_run| {
|
||||
try writer.writeFieldID(6);
|
||||
try writer.writeInt(@as(u8, @boolToInt(dry_run)));
|
||||
}
|
||||
if (this.force) |force| {
|
||||
try writer.writeFieldID(7);
|
||||
try writer.writeInt(@as(u8, @boolToInt(force)));
|
||||
}
|
||||
if (this.save_dev) |save_dev| {
|
||||
try writer.writeFieldID(8);
|
||||
try writer.writeInt(@as(u8, @boolToInt(save_dev)));
|
||||
}
|
||||
if (this.save_optional) |save_optional| {
|
||||
try writer.writeFieldID(9);
|
||||
try writer.writeInt(@as(u8, @boolToInt(save_optional)));
|
||||
}
|
||||
if (this.save_peer) |save_peer| {
|
||||
try writer.writeFieldID(10);
|
||||
try writer.writeInt(@as(u8, @boolToInt(save_peer)));
|
||||
}
|
||||
if (this.save_lockfile) |save_lockfile| {
|
||||
try writer.writeFieldID(11);
|
||||
try writer.writeInt(@as(u8, @boolToInt(save_lockfile)));
|
||||
}
|
||||
if (this.production) |production| {
|
||||
try writer.writeFieldID(12);
|
||||
try writer.writeInt(@as(u8, @boolToInt(production)));
|
||||
}
|
||||
if (this.save_yarn_lockfile) |save_yarn_lockfile| {
|
||||
try writer.writeFieldID(13);
|
||||
try writer.writeInt(@as(u8, @boolToInt(save_yarn_lockfile)));
|
||||
}
|
||||
if (this.native_bin_links) |native_bin_links| {
|
||||
try writer.writeFieldID(14);
|
||||
try writer.writeArray([]const u8, native_bin_links);
|
||||
}
|
||||
if (this.disable_cache) |disable_cache| {
|
||||
try writer.writeFieldID(15);
|
||||
try writer.writeInt(@as(u8, @boolToInt(disable_cache)));
|
||||
}
|
||||
if (this.disable_manifest_cache) |disable_manifest_cache| {
|
||||
try writer.writeFieldID(16);
|
||||
try writer.writeInt(@as(u8, @boolToInt(disable_manifest_cache)));
|
||||
}
|
||||
try writer.endMessage();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
253
src/bunfig.zig
253
src/bunfig.zig
@@ -12,7 +12,6 @@ const URL = @import("./query_string_map.zig").URL;
|
||||
const C = _global.C;
|
||||
const options = @import("./options.zig");
|
||||
const logger = @import("./logger.zig");
|
||||
const cache = @import("./cache.zig");
|
||||
const js_ast = @import("./js_ast.zig");
|
||||
const js_lexer = @import("./js_lexer.zig");
|
||||
const Defines = @import("./defines.zig");
|
||||
@@ -45,6 +44,68 @@ pub const Bunfig = struct {
|
||||
return error.@"Invalid Bunfig";
|
||||
}
|
||||
|
||||
fn parseRegistry(this: *Parser, expr: js_ast.Expr) !Api.NpmRegistry {
|
||||
var registry = std.mem.zeroes(Api.NpmRegistry);
|
||||
|
||||
switch (expr.data) {
|
||||
.e_string => |str| {
|
||||
const url = URL.parse(str.utf8);
|
||||
// Token
|
||||
if (url.username.len == 0 and url.password.len > 0) {
|
||||
registry.token = url.password;
|
||||
registry.url = try std.fmt.allocPrint(this.allocator, "{s}://{s}/{s}", .{ url.displayProtocol(), url.displayHostname(), std.mem.trimLeft(u8, url.pathname, "/") });
|
||||
} else if (url.username.len > 0 and url.password.len > 0) {
|
||||
registry.username = url.username;
|
||||
registry.password = url.password;
|
||||
registry.url = try std.fmt.allocPrint(this.allocator, "{s}://{s}/{s}", .{ url.displayProtocol(), url.displayHostname(), std.mem.trimLeft(u8, url.pathname, "/") });
|
||||
} else {
|
||||
registry.url = url.href;
|
||||
}
|
||||
},
|
||||
.e_object => |obj| {
|
||||
if (obj.get("url")) |url| {
|
||||
try this.expect(url, .e_string);
|
||||
registry.url = url.data.e_string.utf8;
|
||||
}
|
||||
|
||||
if (obj.get("username")) |username| {
|
||||
try this.expect(username, .e_string);
|
||||
registry.username = username.data.e_string.utf8;
|
||||
}
|
||||
|
||||
if (obj.get("password")) |password| {
|
||||
try this.expect(password, .e_string);
|
||||
registry.password = password.data.e_string.utf8;
|
||||
}
|
||||
|
||||
if (obj.get("token")) |token| {
|
||||
try this.expect(token, .e_string);
|
||||
registry.token = token.data.e_string.utf8;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
try this.addError(expr.loc, "Expected registry to be a URL string or an object");
|
||||
},
|
||||
}
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
||||
fn loadLogLevel(this: *Parser, expr: js_ast.Expr) !void {
|
||||
try this.expect(expr, .e_string);
|
||||
const Matcher = strings.ExactSizeMatcher(8);
|
||||
|
||||
this.bunfig.log_level = switch (Matcher.match(expr.asString(this.allocator).?)) {
|
||||
Matcher.case("debug") => Api.MessageLevel.debug,
|
||||
Matcher.case("error") => Api.MessageLevel.err,
|
||||
Matcher.case("warn") => Api.MessageLevel.warn,
|
||||
else => {
|
||||
try this.addError(expr.loc, "Invalid log level, must be one of debug, error, or warn");
|
||||
unreachable;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn parse(this: *Parser, comptime cmd: Command.Tag) !void {
|
||||
const json = this.json;
|
||||
var allocator = this.allocator;
|
||||
@@ -53,6 +114,10 @@ pub const Bunfig = struct {
|
||||
try this.addError(json.loc, "bunfig expects an object { } at the root");
|
||||
}
|
||||
|
||||
if (json.get("logLevel")) |expr| {
|
||||
try this.loadLogLevel(expr);
|
||||
}
|
||||
|
||||
if (json.get("define")) |expr| {
|
||||
try this.expect(expr, .e_object);
|
||||
var valid_count: usize = 0;
|
||||
@@ -89,6 +154,10 @@ pub const Bunfig = struct {
|
||||
this.ctx.debug.fallback_only = disable.asBool() orelse false;
|
||||
}
|
||||
|
||||
if (expr.get("logLevel")) |expr2| {
|
||||
try this.loadLogLevel(expr2);
|
||||
}
|
||||
|
||||
if (expr.get("port")) |port| {
|
||||
try this.expect(port, .e_number);
|
||||
this.bunfig.port = port.data.e_number.toU16();
|
||||
@@ -99,6 +168,169 @@ pub const Bunfig = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (comptime cmd.isNPMRelated()) {
|
||||
if (json.get("install")) |bun| {
|
||||
var install: *Api.BunInstall = this.ctx.install orelse brk: {
|
||||
var install_ = try this.allocator.create(Api.BunInstall);
|
||||
install_.* = std.mem.zeroes(Api.BunInstall);
|
||||
this.ctx.install = install_;
|
||||
break :brk install_;
|
||||
};
|
||||
|
||||
if (bun.get("registry")) |registry| {
|
||||
install.default_registry = try this.parseRegistry(registry);
|
||||
}
|
||||
|
||||
if (bun.get("scopes")) |scopes| {
|
||||
var registry_map = install.scoped orelse std.mem.zeroes(Api.NpmRegistryMap);
|
||||
try this.expect(scopes, .e_object);
|
||||
const count = scopes.data.e_object.properties.len + registry_map.registries.len;
|
||||
var registries = std.ArrayListUnmanaged(Api.NpmRegistry){
|
||||
.items = try this.allocator.alloc(Api.NpmRegistry, count),
|
||||
.capacity = count,
|
||||
};
|
||||
registries.appendSliceAssumeCapacity(registry_map.registries);
|
||||
|
||||
var names = std.ArrayListUnmanaged(string){
|
||||
.items = try this.allocator.alloc(string, count),
|
||||
.capacity = count,
|
||||
};
|
||||
|
||||
names.appendSliceAssumeCapacity(registry_map.names);
|
||||
|
||||
for (scopes.data.e_object.properties.slice()) |prop| {
|
||||
const name_ = prop.key.?.data.e_string.string(this.allocator) orelse continue;
|
||||
const value = prop.value orelse continue;
|
||||
if (name_.len == 0) continue;
|
||||
const name = if (name_[0] == '@') name_[1..] else name_;
|
||||
var index = names.items.len;
|
||||
for (names.items) |comparator, i| {
|
||||
if (strings.eql(name, comparator)) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index == names.items.len) {
|
||||
names.items.len += 1;
|
||||
registries.items.len += 1;
|
||||
}
|
||||
names.items[index] = name;
|
||||
registries.items[index] = try this.parseRegistry(value);
|
||||
}
|
||||
|
||||
registry_map.registries = registries.items;
|
||||
registry_map.names = names.items;
|
||||
install.scoped = registry_map;
|
||||
}
|
||||
|
||||
if (bun.get("dryRun")) |dry_run| {
|
||||
if (dry_run.asBool()) |value| {
|
||||
install.dry_run = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (bun.get("production")) |production| {
|
||||
if (production.asBool()) |value| {
|
||||
install.production = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (bun.get("lockfile")) |lockfile_expr| {
|
||||
if (lockfile_expr.get("outputFormat")) |lockfile| {
|
||||
try this.expect(lockfile, .e_string);
|
||||
if (lockfile.asString(this.allocator)) |value| {
|
||||
if (!(strings.eqlComptime(value, "bun"))) {
|
||||
if (!strings.eqlComptime(value, "yarn")) {
|
||||
try this.addError(lockfile.loc, "Invalid lockfile format, only 'yarn' output is implemented");
|
||||
}
|
||||
|
||||
install.save_yarn_lockfile = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lockfile_expr.get("save")) |lockfile| {
|
||||
if (lockfile.asString()) |value| {
|
||||
install.save_lockfile = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (lockfile_expr.get("path")) |lockfile| {
|
||||
if (lockfile.asString()) |value| {
|
||||
install.lockfile_path = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (lockfile_expr.get("savePath")) |lockfile| {
|
||||
if (lockfile.asString()) |value| {
|
||||
install.save_lockfile_path = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bun.get("optional")) |optional| {
|
||||
if (optional.asBool()) |value| {
|
||||
install.save_optional = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (bun.get("peer")) |optional| {
|
||||
if (optional.asBool()) |value| {
|
||||
install.save_peer = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (bun.get("dev")) |optional| {
|
||||
if (optional.asBool()) |value| {
|
||||
install.save_dev = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (bun.get("logLevel")) |expr| {
|
||||
try this.loadLogLevel(expr);
|
||||
}
|
||||
|
||||
if (bun.get("cache")) |cache| {
|
||||
load: {
|
||||
if (cache.asBool()) |value| {
|
||||
if (!value) {
|
||||
install.disable_cache = true;
|
||||
install.disable_manifest_cache = true;
|
||||
}
|
||||
|
||||
break :load;
|
||||
}
|
||||
|
||||
if (cache.asString(allocator)) |value| {
|
||||
install.cache_directory = value;
|
||||
break :load;
|
||||
}
|
||||
|
||||
if (cache.data == .e_object) {
|
||||
if (cache.get("disable")) |disable| {
|
||||
if (disable.asBool()) |value| {
|
||||
install.disable_cache = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (cache.get("disableManifest")) |disable| {
|
||||
if (disable.asBool()) |value| {
|
||||
install.disable_manifest_cache = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (cache.get("directory")) |directory| {
|
||||
if (directory.asString(allocator)) |value| {
|
||||
install.cache_directory = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (json.get("bundle")) |bun| {
|
||||
if (comptime cmd == .DevCommand or cmd == .BuildCommand or cmd == .RunCommand or cmd == .AutoCommand or cmd == .BunCommand) {
|
||||
if (bun.get("saveTo")) |file| {
|
||||
@@ -108,6 +340,10 @@ pub const Bunfig = struct {
|
||||
}
|
||||
|
||||
if (comptime cmd == .BunCommand) {
|
||||
if (bun.get("logLevel")) |expr2| {
|
||||
try this.loadLogLevel(expr2);
|
||||
}
|
||||
|
||||
if (bun.get("entryPoints")) |entryPoints| {
|
||||
try this.expect(entryPoints, .e_array);
|
||||
const items = entryPoints.data.e_array.items.slice();
|
||||
@@ -224,21 +460,6 @@ pub const Bunfig = struct {
|
||||
};
|
||||
}
|
||||
|
||||
if (json.get("logLevel")) |expr| {
|
||||
try this.expect(expr, .e_string);
|
||||
const Matcher = strings.ExactSizeMatcher(8);
|
||||
|
||||
this.bunfig.log_level = switch (Matcher.match(expr.asString(allocator).?)) {
|
||||
Matcher.case("debug") => Api.MessageLevel.debug,
|
||||
Matcher.case("error") => Api.MessageLevel.err,
|
||||
Matcher.case("warn") => Api.MessageLevel.warn,
|
||||
else => {
|
||||
try this.addError(expr.loc, "Invalid log level, must be one of debug, error, or warn");
|
||||
unreachable;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Analytics.Features.bunfig = true;
|
||||
}
|
||||
|
||||
|
||||
179
src/cli.zig
179
src/cli.zig
@@ -205,6 +205,97 @@ pub const Arguments = struct {
|
||||
Global.exit(0);
|
||||
}
|
||||
|
||||
fn loadConfigPath(allocator: std.mem.Allocator, auto_loaded: bool, config_path: [:0]const u8, ctx: *Command.Context, comptime cmd: Command.Tag) !void {
|
||||
var config_file = std.fs.openFileAbsoluteZ(config_path, .{ .read = true }) catch |err| {
|
||||
if (auto_loaded) return;
|
||||
Output.prettyErrorln("<r><red>error<r>: {s} opening config \"{s}\"", .{
|
||||
@errorName(err),
|
||||
std.mem.span(config_path),
|
||||
});
|
||||
Output.flush();
|
||||
Global.exit(1);
|
||||
};
|
||||
defer config_file.close();
|
||||
var contents = config_file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch |err| {
|
||||
if (auto_loaded) return;
|
||||
Output.prettyErrorln("<r><red>error<r>: {s} reading config \"{s}\"", .{
|
||||
@errorName(err),
|
||||
std.mem.span(config_path),
|
||||
});
|
||||
Output.flush();
|
||||
Global.exit(1);
|
||||
};
|
||||
|
||||
js_ast.Stmt.Data.Store.create(allocator);
|
||||
js_ast.Expr.Data.Store.create(allocator);
|
||||
defer {
|
||||
js_ast.Stmt.Data.Store.reset();
|
||||
js_ast.Expr.Data.Store.reset();
|
||||
}
|
||||
var original_level = ctx.log.level;
|
||||
defer {
|
||||
ctx.log.level = original_level;
|
||||
}
|
||||
ctx.log.level = logger.Log.Level.warn;
|
||||
try Bunfig.parse(allocator, logger.Source.initPathString(std.mem.span(config_path), contents), ctx, cmd);
|
||||
}
|
||||
|
||||
fn getHomeConfigPath(cwd: string, buf: *[std.fs.MAX_PATH_BYTES]u8) ?[:0]const u8 {
|
||||
if (std.os.getenvZ("XDG_CONFIG_HOME")) |data_dir| {
|
||||
var paths = [_]string{ data_dir, ".bunfig.toml" };
|
||||
return resolve_path.joinAbsStringBufZ(cwd, buf, &paths, .auto);
|
||||
}
|
||||
|
||||
if (std.os.getenvZ("HOME")) |data_dir| {
|
||||
var paths = [_]string{ data_dir, ".bunfig.toml" };
|
||||
return resolve_path.joinAbsStringBufZ(cwd, buf, &paths, .auto);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn loadConfig(allocator: std.mem.Allocator, args: clap.Args(clap.Help, ¶ms), ctx: *Command.Context, comptime cmd: Command.Tag) !void {
|
||||
var config_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
if (comptime cmd.readGlobalConfig()) {
|
||||
if (getHomeConfigPath(ctx.args.absolute_working_dir, &config_buf)) |path| {
|
||||
try loadConfigPath(allocator, true, path, ctx, comptime cmd);
|
||||
}
|
||||
}
|
||||
|
||||
var config_path_: []const u8 = "";
|
||||
if (args.option("--config")) |config_path__| {
|
||||
config_path_ = config_path__;
|
||||
}
|
||||
var auto_loaded: bool = false;
|
||||
if (config_path_.len == 0 and (args.option("--config") != null or Command.Tag.always_loads_config.get(cmd))) {
|
||||
config_path_ = "bunfig.toml";
|
||||
auto_loaded = true;
|
||||
}
|
||||
|
||||
if (config_path_.len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var config_path: [:0]u8 = undefined;
|
||||
if (config_path_[0] == '/') {
|
||||
@memcpy(&config_buf, config_path_.ptr, config_path_.len);
|
||||
config_buf[config_path_.len] = 0;
|
||||
config_path = config_buf[0..config_path_.len :0];
|
||||
} else {
|
||||
var parts = [_]string{ ctx.args.absolute_working_dir.?, config_path_ };
|
||||
config_path_ = resolve_path.joinAbsStringBuf(
|
||||
ctx.args.absolute_working_dir.?,
|
||||
&config_buf,
|
||||
&parts,
|
||||
.auto,
|
||||
);
|
||||
config_buf[config_path_.len] = 0;
|
||||
config_path = config_buf[0..config_path_.len :0];
|
||||
}
|
||||
|
||||
try loadConfigPath(allocator, auto_loaded, config_path, ctx, comptime cmd);
|
||||
}
|
||||
|
||||
pub fn parse(allocator: std.mem.Allocator, ctx: *Command.Context, comptime cmd: Command.Tag) !Api.TransformOptions {
|
||||
var diag = clap.Diagnostic{};
|
||||
|
||||
@@ -229,79 +320,14 @@ pub const Arguments = struct {
|
||||
cwd = try std.process.getCwdAlloc(allocator);
|
||||
}
|
||||
|
||||
var opts: Api.TransformOptions = ctx.args;
|
||||
opts.absolute_working_dir = cwd;
|
||||
ctx.args.absolute_working_dir = cwd;
|
||||
|
||||
if (comptime Command.Tag.loads_config.get(cmd)) {
|
||||
load_config: {
|
||||
var config_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
|
||||
var config_path_: []const u8 = "";
|
||||
if (args.option("--config")) |config_path__| {
|
||||
config_path_ = config_path__;
|
||||
}
|
||||
var auto_loaded: bool = false;
|
||||
if (config_path_.len == 0 and (args.option("--config") != null or Command.Tag.always_loads_config.get(cmd))) {
|
||||
config_path_ = "bunfig.toml";
|
||||
auto_loaded = true;
|
||||
}
|
||||
|
||||
if (config_path_.len == 0) {
|
||||
break :load_config;
|
||||
}
|
||||
|
||||
var config_path: [:0]u8 = undefined;
|
||||
if (config_path_[0] == '/') {
|
||||
@memcpy(&config_buf, config_path_.ptr, config_path_.len);
|
||||
config_buf[config_path_.len] = 0;
|
||||
config_path = config_buf[0..config_path_.len :0];
|
||||
} else {
|
||||
var parts = [_]string{ cwd, config_path_ };
|
||||
config_path_ = resolve_path.joinAbsStringBuf(
|
||||
cwd,
|
||||
&config_buf,
|
||||
&parts,
|
||||
.auto,
|
||||
);
|
||||
config_buf[config_path_.len] = 0;
|
||||
config_path = config_buf[0..config_path_.len :0];
|
||||
}
|
||||
|
||||
var config_file = std.fs.openFileAbsoluteZ(config_path, .{ .read = true }) catch |err| {
|
||||
if (auto_loaded) break :load_config;
|
||||
Output.prettyErrorln("<r><red>error<r>: {s} opening config \"{s}\"", .{
|
||||
@errorName(err),
|
||||
std.mem.span(config_path),
|
||||
});
|
||||
Output.flush();
|
||||
Global.exit(1);
|
||||
};
|
||||
var contents = config_file.readToEndAlloc(allocator, std.math.maxInt(usize)) catch |err| {
|
||||
if (auto_loaded) break :load_config;
|
||||
Output.prettyErrorln("<r><red>error<r>: {s} reading config \"{s}\"", .{
|
||||
@errorName(err),
|
||||
std.mem.span(config_path),
|
||||
});
|
||||
Output.flush();
|
||||
Global.exit(1);
|
||||
};
|
||||
|
||||
js_ast.Stmt.Data.Store.create(allocator);
|
||||
js_ast.Expr.Data.Store.create(allocator);
|
||||
defer {
|
||||
js_ast.Stmt.Data.Store.reset();
|
||||
js_ast.Expr.Data.Store.reset();
|
||||
}
|
||||
var original_level = ctx.log.level;
|
||||
defer {
|
||||
ctx.log.level = original_level;
|
||||
}
|
||||
ctx.log.level = logger.Log.Level.warn;
|
||||
try Bunfig.parse(allocator, logger.Source.initPathString(std.mem.span(config_path), contents), ctx, cmd);
|
||||
opts = ctx.args;
|
||||
}
|
||||
try loadConfig(allocator, args, ctx, cmd);
|
||||
}
|
||||
|
||||
var opts: Api.TransformOptions = ctx.args;
|
||||
|
||||
var defines_tuple = try DefineColonList.resolve(allocator, args.options("--define"));
|
||||
|
||||
if (defines_tuple.keys.len > 0) {
|
||||
@@ -699,6 +725,7 @@ pub const Command = struct {
|
||||
log: *logger.Log,
|
||||
allocator: std.mem.Allocator,
|
||||
positionals: []const string = &[_]string{},
|
||||
install: ?*Api.BunInstall = null,
|
||||
|
||||
debug: DebugOptions = DebugOptions{},
|
||||
|
||||
@@ -1126,6 +1153,20 @@ pub const Command = struct {
|
||||
PackageManagerCommand,
|
||||
TestCommand,
|
||||
|
||||
pub fn readGlobalConfig(this: Tag) bool {
|
||||
return switch (this) {
|
||||
.PackageManagerCommand, .InstallCommand, .AddCommand, .RemoveCommand => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn isNPMRelated(this: Tag) bool {
|
||||
return switch (this) {
|
||||
.PackageManagerCommand, .InstallCommand, .AddCommand, .RemoveCommand => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub const cares_about_bun_file: std.EnumArray(Tag, bool) = std.EnumArray(Tag, bool).initDefault(false, .{
|
||||
.AutoCommand = true,
|
||||
.BuildCommand = true,
|
||||
|
||||
@@ -396,6 +396,21 @@ pub const Loader = struct {
|
||||
|
||||
const empty_string_value: string = "\"\"";
|
||||
|
||||
pub fn get(this: *const Loader, key: string) ?string {
|
||||
var _key = key;
|
||||
if (_key.len > 0 and _key[0] == '$') {
|
||||
_key = key[1..];
|
||||
}
|
||||
|
||||
if (_key.len == 0) return null;
|
||||
|
||||
return this.map.get(_key);
|
||||
}
|
||||
|
||||
pub fn getAuto(this: *const Loader, key: string) string {
|
||||
return this.get(key) orelse key;
|
||||
}
|
||||
|
||||
/// Load values from the environment into Define.
|
||||
///
|
||||
/// If there is a framework, values from the framework are inserted with a
|
||||
|
||||
@@ -36,6 +36,24 @@ pub fn append(this: *HeaderBuilder, name: string, value: string) void {
|
||||
this.entries.appendAssumeCapacity(Headers.Kv{ .name = name_ptr, .value = value_ptr });
|
||||
}
|
||||
|
||||
pub fn appendFmt(this: *HeaderBuilder, name: string, comptime fmt: string, args: anytype) void {
|
||||
const name_ptr = Api.StringPointer{
|
||||
.offset = @truncate(u32, this.content.len),
|
||||
.length = @truncate(u32, name.len),
|
||||
};
|
||||
|
||||
_ = this.content.append(name);
|
||||
|
||||
const value = this.content.fmt(fmt, args);
|
||||
|
||||
const value_ptr = Api.StringPointer{
|
||||
.offset = @truncate(u32, this.content.len),
|
||||
.length = @truncate(u32, value.len),
|
||||
};
|
||||
|
||||
this.entries.appendAssumeCapacity(Headers.Kv{ .name = name_ptr, .value = value_ptr });
|
||||
}
|
||||
|
||||
pub fn apply(this: *HeaderBuilder, client: *HTTPClient) void {
|
||||
client.header_entries = this.entries;
|
||||
client.header_buf = this.content.ptr.?[0..this.content.len];
|
||||
|
||||
@@ -30,3 +30,14 @@ pub fn append(this: *StringBuilder, slice: string) string {
|
||||
assert(this.len <= this.cap);
|
||||
return result;
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
pub fn fmt(this: *StringBuilder, comptime str: string, args: anytype) string {
|
||||
assert(this.len <= this.cap); // didn't count everything
|
||||
assert(this.ptr != null); // must call allocate first
|
||||
|
||||
var buf = this.ptr.?[this.len..this.cap];
|
||||
const out = std.fmt.bufPrint(buf, str, args) catch unreachable;
|
||||
this.len += out.len;
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user