if command_tag.tag.require_config_file {
if !load_config_file() {
- eprintf("Failed to open {}.\n", global_arguments.config_file);
+ error_print("Failed to open {}.\n", global_arguments.config_file);
os.exit(1);
}
#tag Command.{ "init", "Initialize a new project.", "", require_config_file=false }
run_init_command :: (args: [] cstr) {
if os.file_exists(global_arguments.config_file) {
- eprintf("Config file present; project already initialized.\n");
+ error_print("Config file present; project already initialized.\n");
return;
}
}
run_add_command :: (args: [] cstr) {
if args.count < 1 {
- eprintf("Expected package name.");
+ error_print("Expected package URL");
return;
}
version: SemVer;
if args.count > 1 {
if !conv.parse_any(&version, string.as_str(args[1])) {
- eprintf("Failed to parse version number given: {}\n", string.as_str(args[1]));
+ error_print("Failed to parse version number given: {}\n", string.as_str(args[1]));
return;
}
}
if config.dependencies.dependencies->has(dep) {
- eprintf("Dependency '{}' already specified at version '{}'.\n", dep, config.dependencies.dependencies[dep]);
+ error_print("Dependency '{}' already specified at version '{}'.\n", dep, config.dependencies.dependencies[dep]);
} elseif version->is_zero() {
- printf("Unable to find latest version of '{}'.\n", dep);
+ error_print("Unable to find latest version of '{}'\n", string.as_str(args[0]));
} else {
config.dependencies.dependencies[dep] = version;
- printf("Added dependency '{}' at version {}.\n", dep, version);
+ info_print("Added", "'{}' version {}\n", dep, version);
}
}
}
run_remove_command :: (args: [] cstr) {
if args.count < 1 {
- eprintf("Expected package name.");
+ error_print("Expected package name.");
return;
}
}
}
- eprintf("Dependency '{}' is not currently used.\n", dep);
+ error_print("Dependency '{}' is not currently used.\n", dep);
}
#tag Command.{ "show", "Show dependencies and versions.", "" }
#tag Command.{ "update", "Update dependencies to newest compatible versions.", "" }
// @Feature // Add "locked" dependencies that will never update?
run_update_command :: (args: [] cstr) {
- printf("Updating dependencies to newest compatible versions.\n");
+ info_print("Info", "Updating dependencies to newest compatible versions.\n");
for& config.dependencies.dependencies.entries {
new_version := Git.get_latest_compatible_version(it.key, it.value);
- printf("{}: {} -> {}\n", it.key, it.value, new_version);
+ if it.value != new_version {
+ info_print("Update", "{} {} -> {}\n", it.key, it.value, new_version);
+ }
it.value = new_version;
}
success, installed_folder := install_package(to_install.pack, to_install.downgrade_if_necessary);
if !success {
- eprintf("Aborting sync.\n");
+ error_print("Aborting sync.\n");
return;
}
result, error := encoding.ini.parse_ini_file(&r, &inner_config);
if result != .Success {
- eprintf("Failed to parse onyx-pkg.ini in {}. Skipping...\n", to_install.repo);
+ error_print("Misconfigured onyx-pkg.ini in '{}'. Omitting.\n", to_install.repo);
continue;
}
}
if inner_config.metadata.version->is_zero() {
- eprintf("Failed to parse onyx-pkg.ini in {}. Skipping...\n", to_install.repo);
+ error_print("Misconfigured parse onyx-pkg.ini in '{}'. Omitting.\n", to_install.repo);
continue;
}
for& inner_config.dependencies.dependencies.entries {
if dependencies_installed->has(it.key) {
+ // TODO : Check if this is right? Could this accidentally forcefully upgrade a package?
if it.value->is_newer(dependencies_installed[it.key]) {
uninstall_package(.{it.key, it.value});
dependencies_installed->delete(it.key);
dependencies_to_install << .{ .{it.key, it.value}, false };
} elseif !(it.value->is_compatible(dependencies_installed[it.key])) {
- eprintf("Different major versions of {} being used!\n", it.key);
+ // TODO: Explain this more
+ error_print("Different major versions of '{}' being used!\n", it.key);
os.exit(1);
}
} else {
if it.type != .Directory do continue;
if !array.contains(needed_dependency_folders, it->name()) {
+ info_print("Remove", "{}\n", it->name());
package_folder := tprintf("{}/{}", config.config.lib_source_directory, it->name());
attempt_remove_native_library(package_folder);
os.remove_directory(package_folder);
}
run_rebuild_command :: (args: [] cstr) {
if args.count < 1 {
- eprintf("Expected package name.");
+ error_print("Expected package name.");
return;
}
folder = config.dependency_folders.folders[dep];
}
- if rebuild_native_library(folder) {
- printf("Successfully rebuilt {}.\n", dep);
+ info_print("Rebuild", "{}\n", dep);
+ if success, err := rebuild_native_library(folder); success {
+ info_print("Rebuilt", "{}\n", dep);
} else {
- printf("Failed to rebuild {}.\n", dep);
+ error_print("Rebuild failed.\n", dep);
+ println(err);
os.exit(1);
}
}
// @TODO // Better error handling and reporting, as this is a delicate process.
if !os.dir_exists(".git") {
+ error_print("Not in Git repository.\n");
printf("It does not look like you are in a Git repository. In order to publish packages\n");
printf("with onyx-pkg, you have to initailize a Git repository in the current directory.\n\n");
return;
store_config_file();
- printf("Creating new published version...\n");
+ info_print("Publishing", "Creating new published version\n");
if Git.publish_version() {
- printf("Successfully published new version.\n");
+ info_print("Published", "Successfully published new version.\n");
} else {
- printf("Failed to publish new version.\n");
+ error_print("Failed to publish new version.\n");
}
}
installed_version := get_installed_version_of_package(folder_name);
if installed_version == pack.version {
- printf("{} is already installed at version {}.\n", pack.repo, installed_version);
+ info_print("Exists", "{} {}\n", pack.repo, installed_version);
return true, folder_name;
}
if installed_version->is_newer(pack.version) && !downgrade_if_necessary {
- eprintf("Refusing to downgrade package {} from version {} to {}.\n", pack.repo, installed_version, pack.version);
+ error_print("Refusing to downgrade '{}' from {} to {}.\n", pack.repo, installed_version, pack.version);
}
+ // :PRETTY
verb := "Upgrading" if pack.version->is_newer(installed_version) else "Downgrading";
- printf("{} package {} from version {} to {}.\n", verb, pack.repo, installed_version, pack.version);
+ info_print(verb, "{} {} -> {}\n", pack.repo, installed_version, pack.version);
uninstall_package(pack);
}
}
if !Git.clone_version(pack.repo, pack.version) {
- eprintf("Failed to fetch {} version {}.\n", pack.repo, pack.version);
+ error_print("Failed to fetch {} version {}.\n", pack.repo, pack.version);
return false, "";
}
return true;
}
-rebuild_native_library :: (folder: str) -> bool {
+rebuild_native_library :: (folder: str) -> (bool, str) {
attempt_remove_native_library(tprintf("{}/{}", config.config.lib_source_directory, folder));
- return run_native_library_installation(folder);
+ success, build_error := run_native_library_installation(folder);
+ return success, build_error;
}
get_installed_version_of_package :: (package_path: str) -> SemVer {
return .{0, 0, 0};
}
-run_native_library_installation :: (folder: str) -> bool {
+run_native_library_installation :: (folder: str) -> (bool, str) {
inner_config: Config;
for os.with_file(tprintf("{}/{}/onyx-pkg.ini", config.config.lib_source_directory, folder)) {
r := io.reader_make(it);
result, error := encoding.ini.parse_ini_file(&r, &inner_config);
- if result != .Success do return false;
- if string.empty(inner_config.native_library.build_cmd) do return true;
+ if result != .Success do return false, "";
+ if string.empty(inner_config.native_library.build_cmd) do return true, "";
args := string.split(inner_config.native_library.build_cmd, #char " ", context.temp_allocator);
cmd := args[0];
args = args[1 .. args.count];
installed_dest := tprintf("{}/{}", config.config.lib_source_directory, folder);
- build_proc := os.process_spawn(cmd, args, starting_directory=installed_dest);
- build_result := os.process_wait(&build_proc);
- if build_result != .Success {
- eprintf("Failed to build native library in {}.\n", folder);
- return false;
+ {
+ build_proc := os.process_spawn(cmd, args, starting_directory=installed_dest);
+ build_reader := io.reader_make(&build_proc);
+ defer io.reader_free(&build_reader);
+
+ build_result := os.process_wait(&build_proc);
+ if build_result != .Success {
+ error_print("Failed to build native library in {}.\n", folder);
+ return false, build_reader->read_all();
+ }
}
if !os.dir_exists(config.config.lib_bin_directory) {
if !os.dir_create(config.config.lib_bin_directory) {
- eprintf("Failed to create native library directory, {}.\n", config.config.lib_bin_directory);
- return false;
+ error_print("Failed to create native library directory, {}.\n", config.config.lib_bin_directory);
+ return false, "";
}
}
success := os.rename_file(source_path, dest_path);
if !success {
- eprintf("Failed to move native library to final destination.\n {} -> {}\n", source_path, dest_path);
+ error_print("Failed to move native library to final destination.\n {} -> {}\n", source_path, dest_path);
}
- return success;
+ return success, "";
}
}
}
clone_version :: (repo: str, version: SemVer) -> bool {
- printf("Fetching {} version {}...\n", repo, version);
+ info_print("Fetch", "{} {}\n", repo, version);
version_str := tprintf("v{}", version);
full_dest := tprintf("{}/{}", config.config.lib_source_directory, ".cloned");
}
if !successfully_parsed {
- eprintf("Unknown destination directory and failed to find onyx-pkg.ini in {}.\n", repo);
+ error_print("Unknown destination directory and failed to find onyx-pkg.ini in {}.\n", repo);
os.remove_directory(full_dest);
return false;
}
// Move the cloned repository to its permanent location.
actual_dest := tprintf("{}/{}", config.config.lib_source_directory, install_dest);
if os.dir_exists(actual_dest) {
- eprintf("Expected {} to not exist when fetching {}.\n", actual_dest, repo);
+ error_print("Expected {} to not exist when fetching '{}'.\n", actual_dest, repo);
os.remove_directory(full_dest);
return false;
}
if !os.dir_rename(full_dest, actual_dest) {
- eprintf("Failed to move temporary package to final destination when fetching {}.\n", repo);
+ error_print("Failed to move temporary package to final destination when fetching '{}'.\n", repo);
os.remove_directory(full_dest);
return false;
}
// Remove the .git folder, as it is unneeded.
unnecessary_git_dir := tprintf("{}/.git", actual_dest);
if !os.remove_directory(unnecessary_git_dir) {
- eprintf("Failed to delete .git folder of {}.\n", repo);
+ error_print("Failed to delete .git folder of '{}'.\n", repo);
return false;
}
}
+Color_Print :: struct {
+ Color :: enum {
+ Black;
+ Red;
+ Green;
+ Yellow;
+ Blue;
+ Purple;
+ Cyan;
+ White;
+ __Unused;
+ Default;
+ }
+
+ color: Color;
+ text: str;
+}
+
+color_print :: (segments: ..Color_Print) {
+ for segments {
+ printf("\x1b[3{}m{}", cast(u32) it.color, it.text);
+ }
+
+ print("\x1b[0m");
+}
+
+error_print :: (text: str, va: ..any) {
+ buf: [1024] u8;
+ color_print(
+ .{ .Red, " Error " },
+ .{ .Default, conv.format_va(buf, text, cast([] any) va) }
+ );
+}
+
+info_print :: (verb: str, text: str, va: ..any) {
+ buf: [1024] u8;
+
+ // HACK
+ for 12 - verb.length do print(" ");
+
+ color_print(
+ .{ .Green, tprintf("{} ", verb) },
+ .{ .Default, conv.format_va(buf, text, cast([] any) va) }
+ );
+}
+