Initial Commit
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
./index
|
||||
.zig-cache
|
||||
zig-out
|
||||
@@ -0,0 +1,24 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "xpk",
|
||||
.root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize }),
|
||||
});
|
||||
|
||||
b.installArtifact(exe);
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
|
||||
if (b.args) |args| {
|
||||
run_cmd.addArgs(args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
.{
|
||||
.name = .xpk,
|
||||
.version = "0.0.0",
|
||||
|
||||
.fingerprint = 0x50fc21dcc3f3cc25,
|
||||
.minimum_zig_version = "0.16.0",
|
||||
.dependencies = .{},
|
||||
|
||||
.paths = .{ "build.zig", "build.zig.zon", "src", ".gitignore" },
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
description A small example package
|
||||
license MIT
|
||||
@@ -0,0 +1,8 @@
|
||||
pub const installed_directory = "./installed";
|
||||
pub const index_directory = "./index";
|
||||
|
||||
pub const arch = "x86_64";
|
||||
|
||||
pub const repos = .{
|
||||
.main = "http://localhost:3000",
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
const std = @import("std");
|
||||
|
||||
const config = @import("config.zig");
|
||||
|
||||
pub fn load(
|
||||
init: std.process.Init,
|
||||
repo_name: []const u8,
|
||||
package_name: []const u8,
|
||||
) ![]u8 {
|
||||
const allocator = init.gpa;
|
||||
const cwd = std.Io.Dir.cwd();
|
||||
|
||||
const path = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{s}/{s}/{s}.mt",
|
||||
.{
|
||||
config.index_directory,
|
||||
repo_name,
|
||||
package_name,
|
||||
},
|
||||
);
|
||||
defer allocator.free(path);
|
||||
|
||||
return try cwd.readFileAlloc(
|
||||
init.io,
|
||||
path,
|
||||
allocator,
|
||||
.limited(1024 * 1024),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
const std = @import("std");
|
||||
|
||||
const index = @import("index.zig");
|
||||
|
||||
pub fn run(init: std.process.Init, args: []const [:0]const u8) !void {
|
||||
if (args.len < 3) {
|
||||
std.debug.print("usage: xpk install <package>\n", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
const package_name = args[2];
|
||||
|
||||
const metadata = index.load(
|
||||
init,
|
||||
"main",
|
||||
package_name,
|
||||
) catch |err| {
|
||||
if (err == error.FileNotFound) {
|
||||
std.debug.print(
|
||||
"package '{s}' is not in the local index\n",
|
||||
.{package_name},
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
return err;
|
||||
};
|
||||
defer init.gpa.free(metadata);
|
||||
|
||||
std.debug.print(
|
||||
"metadata for {s}:\n{s}\n",
|
||||
.{
|
||||
package_name,
|
||||
metadata,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
|
||||
const config = @import("config.zig");
|
||||
const network = @import("network.zig");
|
||||
const install = @import("install.zig");
|
||||
const repo = @import("repo.zig");
|
||||
|
||||
const Command = enum {
|
||||
install,
|
||||
remove,
|
||||
sync,
|
||||
search,
|
||||
info,
|
||||
};
|
||||
|
||||
fn parse_command(name: []const u8) !Command {
|
||||
if (std.mem.eql(u8, name, "install")) return .install;
|
||||
if (std.mem.eql(u8, name, "remove")) return .remove;
|
||||
if (std.mem.eql(u8, name, "sync")) return .sync;
|
||||
if (std.mem.eql(u8, name, "search")) return .search;
|
||||
if (std.mem.eql(u8, name, "info")) return .info;
|
||||
|
||||
return error.UnknownCommand;
|
||||
}
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const arena = init.arena.allocator();
|
||||
|
||||
const args = try init.minimal.args.toSlice(arena);
|
||||
|
||||
if (args.len < 2) {
|
||||
std.debug.print("usage: xpk <command>\n", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
const command = try parse_command(args[1]);
|
||||
|
||||
switch (command) {
|
||||
.install => try install.run(init, args),
|
||||
|
||||
.remove => {
|
||||
// later
|
||||
},
|
||||
|
||||
.sync => try repo.sync(init),
|
||||
|
||||
.search => {
|
||||
// later
|
||||
},
|
||||
|
||||
.info => {
|
||||
// later
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn download(
|
||||
io: std.Io,
|
||||
allocator: std.mem.Allocator,
|
||||
url: []const u8,
|
||||
path: []const u8,
|
||||
) !void {
|
||||
var client = std.http.Client{
|
||||
.allocator = allocator,
|
||||
.io = io,
|
||||
};
|
||||
defer client.deinit();
|
||||
|
||||
const cwd = std.Io.Dir.cwd();
|
||||
|
||||
var file = try cwd.createFile(io, path, .{});
|
||||
defer file.close(io);
|
||||
|
||||
var writer_buffer: [64 * 1024]u8 = undefined;
|
||||
var writer = file.writer(io, &writer_buffer);
|
||||
|
||||
const response = try client.fetch(.{
|
||||
.location = .{ .url = url },
|
||||
.response_writer = &writer.interface,
|
||||
});
|
||||
|
||||
if (response.status != .ok) {
|
||||
return error.HttpError;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(
|
||||
io: std.Io,
|
||||
allocator: std.mem.Allocator,
|
||||
url: []const u8,
|
||||
) ![]u8 {
|
||||
var client = std.http.Client{
|
||||
.allocator = allocator,
|
||||
.io = io,
|
||||
};
|
||||
defer client.deinit();
|
||||
|
||||
var body = std.Io.Writer.Allocating.init(allocator);
|
||||
defer body.deinit();
|
||||
|
||||
const response = try client.fetch(.{
|
||||
.location = .{ .url = url },
|
||||
.response_writer = &body.writer,
|
||||
});
|
||||
|
||||
if (response.status != .ok) {
|
||||
return error.HttpError;
|
||||
}
|
||||
|
||||
return body.toOwnedSlice();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const Package = struct {
|
||||
name: []const u8,
|
||||
version: []const u8,
|
||||
description: ?[]const u8,
|
||||
license: ?[]const u8,
|
||||
};
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
const std = @import("std");
|
||||
|
||||
const config = @import("config.zig");
|
||||
const network = @import("network.zig");
|
||||
|
||||
pub fn sync(init: std.process.Init) !void {
|
||||
const allocator = init.gpa;
|
||||
const repo = "main";
|
||||
|
||||
const list_url = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{s}/{s}/{s}/.mt",
|
||||
.{
|
||||
config.repos.main,
|
||||
repo,
|
||||
config.arch,
|
||||
},
|
||||
);
|
||||
defer allocator.free(list_url);
|
||||
|
||||
std.debug.print("syncing {s}\n", .{list_url});
|
||||
|
||||
const list = try network.get(
|
||||
init.io,
|
||||
allocator,
|
||||
list_url,
|
||||
);
|
||||
defer allocator.free(list);
|
||||
|
||||
const cwd = std.Io.Dir.cwd();
|
||||
|
||||
cwd.createDir(
|
||||
init.io,
|
||||
config.index_directory,
|
||||
.default_dir,
|
||||
) catch |err| switch (err) {
|
||||
error.PathAlreadyExists => {},
|
||||
else => return err,
|
||||
};
|
||||
|
||||
const index_path = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{s}/{s}",
|
||||
.{
|
||||
config.index_directory,
|
||||
repo,
|
||||
},
|
||||
);
|
||||
defer allocator.free(index_path);
|
||||
|
||||
cwd.createDir(
|
||||
init.io,
|
||||
index_path,
|
||||
.default_dir,
|
||||
) catch |err| switch (err) {
|
||||
error.PathAlreadyExists => {},
|
||||
else => return err,
|
||||
};
|
||||
|
||||
var lines = std.mem.splitScalar(u8, list, '\n');
|
||||
|
||||
while (lines.next()) |line| {
|
||||
const package = std.mem.trim(u8, line, " \r\t");
|
||||
|
||||
if (package.len == 0)
|
||||
continue;
|
||||
|
||||
const url = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{s}/{s}/{s}/{s}/.mt",
|
||||
.{
|
||||
config.repos.main,
|
||||
repo,
|
||||
config.arch,
|
||||
package,
|
||||
},
|
||||
);
|
||||
defer allocator.free(url);
|
||||
|
||||
std.debug.print(" {s}\n", .{package});
|
||||
|
||||
const metadata = try network.get(
|
||||
init.io,
|
||||
init.gpa,
|
||||
url,
|
||||
);
|
||||
defer init.gpa.free(metadata);
|
||||
|
||||
const path = try std.fmt.allocPrint(
|
||||
allocator,
|
||||
"{s}/{s}.mt",
|
||||
.{
|
||||
index_path,
|
||||
package,
|
||||
},
|
||||
);
|
||||
defer allocator.free(path);
|
||||
|
||||
var file = try cwd.createFile(
|
||||
init.io,
|
||||
path,
|
||||
.{},
|
||||
);
|
||||
defer file.close(init.io);
|
||||
|
||||
try file.writeStreamingAll(
|
||||
init.io,
|
||||
metadata,
|
||||
);
|
||||
}
|
||||
|
||||
std.debug.print("sync complete\n", .{});
|
||||
}
|
||||
Reference in New Issue
Block a user