Skip to content

Commit

Permalink
Merge pull request #48 from shilangyu/feat/debug-logging
Browse files Browse the repository at this point in the history
Add debug logging
  • Loading branch information
shilangyu authored Jul 8, 2024
2 parents 03dc8f1 + fd09d20 commit b58f87b
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 11 deletions.
22 changes: 22 additions & 0 deletions .github/ISSUE_TEMPLATE/---bug-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
name: "\U0001F41B Bug report"
about: Report a bug
title: ""
labels: bug
assignees: ""
---

## Description

<!-- Bug description goes here -->

## Logs

The offending command causing the error with the `$env:SCOOP_SEARCH_VERBOSE=1` env var set:

<details>
<summary>Output</summary>
<!-- For example if `scoop-search qwerty` causes some unwanted behavior, paste the output of `$env:SCOOP_SEARCH_VERBOSE=1 ; scoop-search qwerty ; $env:SCOOP_SEARCH_VERBOSE=$null` below -->
```txt
```
</details>
35 changes: 27 additions & 8 deletions src/env.zig
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
const std = @import("std");
const utils = @import("utils.zig");
const testing = std.testing;
const DebugLogger = utils.DebugLogger;

/// Checks if scoop-search should run in verbose mode.
pub fn isVerbose() bool {
return std.process.hasEnvVarConstant("SCOOP_SEARCH_VERBOSE");
}

/// Gets the home directory of the current user.
fn homeDirOwned(allocator: std.mem.Allocator) !?[]const u8 {
const dir = std.process.getEnvVarOwned(allocator, "USERPROFILE") catch |err| switch (err) {
fn homeDirOwned(allocator: std.mem.Allocator, debug: DebugLogger) !?[]const u8 {
const userProfile = std.process.getEnvVarOwned(allocator, "USERPROFILE");
try debug.log("env:USERPROFILE={s}\n", .{userProfile catch ""});

const dir = userProfile catch |err| switch (err) {
error.EnvironmentVariableNotFound => return null,
else => |e| return e,
};
Expand All @@ -18,8 +27,11 @@ fn homeDirOwned(allocator: std.mem.Allocator) !?[]const u8 {
}

/// Path to the scoop config file.
fn scoopConfigFileOwned(allocator: std.mem.Allocator, homeDir: ?[]const u8) ![]const u8 {
const systemConfig = std.process.getEnvVarOwned(allocator, "XDG_CONFIG_HOME") catch |err| switch (err) {
fn scoopConfigFileOwned(allocator: std.mem.Allocator, homeDir: ?[]const u8, debug: DebugLogger) ![]const u8 {
const xdgConfigHome = std.process.getEnvVarOwned(allocator, "XDG_CONFIG_HOME");
try debug.log("env:XDG_CONFIG_HOME={s}\n", .{xdgConfigHome catch ""});

const systemConfig = xdgConfigHome catch |err| switch (err) {
error.EnvironmentVariableNotFound => if (homeDir) |dir|
try utils.concatOwned(allocator, dir, "/.config")
else
Expand All @@ -32,21 +44,26 @@ fn scoopConfigFileOwned(allocator: std.mem.Allocator, homeDir: ?[]const u8) ![]c
}

/// Returns the path to the root of scoop. Logic follows Scoop's logic for resolving the home directory.
pub fn scoopHomeOwned(allocator: std.mem.Allocator) ![]const u8 {
return std.process.getEnvVarOwned(allocator, "SCOOP") catch |err| switch (err) {
pub fn scoopHomeOwned(allocator: std.mem.Allocator, debug: DebugLogger) ![]const u8 {
const scoop = std.process.getEnvVarOwned(allocator, "SCOOP");
try debug.log("env:SCOOP={s}\n", .{scoop catch ""});

return scoop catch |err| switch (err) {
error.EnvironmentVariableNotFound => {
const homeDir = try homeDirOwned(allocator);
const homeDir = try homeDirOwned(allocator, debug);
defer {
if (homeDir) |d| allocator.free(d);
}
const scoopConfigPath = try scoopConfigFileOwned(allocator, homeDir);
const scoopConfigPath = try scoopConfigFileOwned(allocator, homeDir, debug);
defer allocator.free(scoopConfigPath);
try debug.log("Scoop config file path: {s}\n", .{scoopConfigPath});

if (std.fs.openFileAbsolute(scoopConfigPath, .{}) catch null) |configFile| {
defer configFile.close();

if (utils.readFileOwned(allocator, configFile) catch null) |config| {
defer allocator.free(config);
try debug.log("Scoop config file contents: {s}\n", .{config});

const parsed = try std.json.parseFromSlice(struct { root_path: ?[]const u8 = null }, allocator, config, .{ .ignore_unknown_fields = true });
defer parsed.deinit();
Expand All @@ -56,6 +73,8 @@ pub fn scoopHomeOwned(allocator: std.mem.Allocator) ![]const u8 {
return allocator.dupe(u8, rootPath);
}
}
} else {
try debug.log("Scoop config file does not exist\n", .{});
}

// installing with default directory doesn't have `SCOOP`
Expand Down
12 changes: 10 additions & 2 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,20 @@ pub fn main() !void {
std.process.exit(0);
}

const debug = utils.DebugLogger.init(env.isVerbose());
try debug.log("Commandline arguments: {}\n", .{args});

const query = try std.ascii.allocLowerString(allocator, args.query orelse "");
defer allocator.free(query);

const scoopHome = env.scoopHomeOwned(allocator) catch |err| switch (err) {
const scoopHome = env.scoopHomeOwned(allocator, debug) catch |err| switch (err) {
error.MissingHomeDir => {
return std.io.getStdErr().writer().print("Could not establish scoop home directory. USERPROFILE environment variable is not defined.\n", .{});
},
else => |e| return e,
};
defer allocator.free(scoopHome);
try debug.log("Scoop home: {s}\n", .{scoopHome});

// get buckets path
const bucketsPath = try utils.concatOwned(allocator, scoopHome, "/buckets");
Expand All @@ -73,11 +77,13 @@ pub fn main() !void {

const bucketBase = try std.mem.concat(allocator, u8, &[_][]const u8{ bucketsPath, "/", f.name });
defer allocator.free(bucketBase);
try debug.log("Found bucket: {s}\n", .{bucketBase});

const result = search.searchBucket(allocator, query, bucketBase) catch {
const result = search.searchBucket(allocator, query, bucketBase, debug) catch {
try std.io.getStdErr().writer().print("Failed to search through the bucket: {s}.\n", .{f.name});
continue;
};
try debug.log("Found {} matches\n", .{result.matches.items.len});

try results.append(try SearchResult.init(
allocator,
Expand All @@ -86,6 +92,8 @@ pub fn main() !void {
));
}

try debug.log("Done searching\n", .{});

const hasMatches = try printResults(allocator, &results);
if (!hasMatches)
std.process.exit(1);
Expand Down
4 changes: 3 additions & 1 deletion src/search.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const utils = @import("utils.zig");
const Box = utils.Box;
const DebugLogger = utils.DebugLogger;

/// State associated with a worker thread. Stores thread local cache and matches. Has its own allocator.
const ThreadPoolState = struct {
Expand Down Expand Up @@ -118,9 +119,10 @@ fn getPackagesDir(allocator: std.mem.Allocator, bucketBase: []const u8) !std.fs.
return packages;
}

pub fn searchBucket(allocator: std.mem.Allocator, query: []const u8, bucketBase: []const u8) !SearchResult {
pub fn searchBucket(allocator: std.mem.Allocator, query: []const u8, bucketBase: []const u8, debug: DebugLogger) !SearchResult {
var tp: ThreadPool = undefined;
try tp.init(.{ .allocator = allocator }, ThreadPoolState.create);
try debug.log("Worker count: {}\n", .{tp.threads.len});

var packages = try getPackagesDir(allocator, bucketBase);
defer packages.close();
Expand Down
12 changes: 12 additions & 0 deletions src/utils.zig
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,15 @@ pub fn Box(comptime T: type) type {
}
};
}

pub const DebugLogger = struct {
writer: ?std.fs.File.Writer,

pub fn init(enabled: bool) @This() {
return .{ .writer = if (enabled) std.io.getStdErr().writer() else null };
}

pub inline fn log(self: @This(), comptime format: []const u8, args: anytype) !void {
if (self.writer) |out| try out.print(format, args);
}
};

0 comments on commit b58f87b

Please sign in to comment.