Reworked the build file searching method
Instead of looking for any existing build file in the store that fits in the directory structure of a new document, we now always look for the closest build.zig file in the directory structure.
This commit is contained in:
		
							parent
							
								
									1408aa733b
								
							
						
					
					
						commit
						ca6598572e
					
				@ -75,7 +75,7 @@ fn loadPackages(context: LoadPackagesContext) !void {
 | 
			
		||||
 | 
			
		||||
    const build_file_path = try URI.parse(allocator, build_file.uri);
 | 
			
		||||
    defer allocator.free(build_file_path);
 | 
			
		||||
    const directory_path = build_file_path[0..build_file_path.len - "build.zig".len];
 | 
			
		||||
    const directory_path = build_file_path[0 .. build_file_path.len - "build.zig".len];
 | 
			
		||||
 | 
			
		||||
    const zig_run_result = try std.ChildProcess.exec(.{
 | 
			
		||||
        .allocator = allocator,
 | 
			
		||||
@ -191,55 +191,68 @@ fn newDocument(self: *DocumentStore, uri: []const u8, text: []u8) anyerror!*Hand
 | 
			
		||||
        }) catch |err| {
 | 
			
		||||
            log.debug("Failed to load packages of build file {s} (error: {})", .{ build_file.uri, err });
 | 
			
		||||
        };
 | 
			
		||||
    } else if (self.zig_exe_path != null and !in_std) associate_build_file: {
 | 
			
		||||
        // Look into build files to see if we already have one that fits
 | 
			
		||||
        for (self.build_files.items) |build_file| {
 | 
			
		||||
    } else if (self.zig_exe_path != null and !in_std) {
 | 
			
		||||
        // Look into build files to see if we already have one that lives in the directory structure
 | 
			
		||||
        var candidate = for (self.build_files.items) |build_file| {
 | 
			
		||||
            const build_file_base_uri = build_file.uri[0 .. std.mem.lastIndexOfScalar(u8, build_file.uri, '/').? + 1];
 | 
			
		||||
 | 
			
		||||
            if (std.mem.startsWith(u8, uri, build_file_base_uri)) {
 | 
			
		||||
                log.debug("Found an associated build file: {s}", .{build_file.uri});
 | 
			
		||||
                build_file.refs += 1;
 | 
			
		||||
                handle.associated_build_file = build_file;
 | 
			
		||||
                break :associate_build_file;
 | 
			
		||||
                log.debug("Found a candidate associated build file: {s}", .{build_file.uri});
 | 
			
		||||
                break build_file;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Otherwise, try to find a build file.
 | 
			
		||||
        } else null;
 | 
			
		||||
        // Then, try to find the closest build file.
 | 
			
		||||
        var curr_path = try URI.parse(self.allocator, uri);
 | 
			
		||||
        defer self.allocator.free(curr_path);
 | 
			
		||||
        while (true) {
 | 
			
		||||
            if (curr_path.len == 0) break :associate_build_file;
 | 
			
		||||
            if (curr_path.len == 0) break;
 | 
			
		||||
 | 
			
		||||
            if (std.mem.lastIndexOfScalar(u8, curr_path[0 .. curr_path.len - 1], std.fs.path.sep)) |idx| {
 | 
			
		||||
                // This includes the last separator
 | 
			
		||||
                curr_path = curr_path[0 .. idx + 1];
 | 
			
		||||
 | 
			
		||||
                // Try to open the folder, then the file.
 | 
			
		||||
                var folder = std.fs.cwd().openDir(curr_path, .{}) catch |err| switch (err) {
 | 
			
		||||
                    error.FileNotFound => continue,
 | 
			
		||||
                    else => return err,
 | 
			
		||||
                };
 | 
			
		||||
                defer folder.close();
 | 
			
		||||
 | 
			
		||||
                // Try to open the file, read it and add the new document if we find it.
 | 
			
		||||
                const build_file_text = folder.readFileAlloc(self.allocator, "build.zig", std.math.maxInt(usize)) catch |err| switch (err) {
 | 
			
		||||
                var build_file = folder.openFile("build.zig", .{}) catch |err| switch (err) {
 | 
			
		||||
                    error.FileNotFound, error.AccessDenied => continue,
 | 
			
		||||
                    else => return err,
 | 
			
		||||
                };
 | 
			
		||||
                errdefer self.allocator.free(build_file_text);
 | 
			
		||||
                defer build_file.close();
 | 
			
		||||
 | 
			
		||||
                // Calculate build file's URI
 | 
			
		||||
                var candidate_path = try std.mem.concat(self.allocator, u8, &[_][]const u8{ curr_path, "build.zig" });
 | 
			
		||||
                defer self.allocator.free(candidate_path);
 | 
			
		||||
 | 
			
		||||
                const build_file_uri = try URI.fromPath(self.allocator, candidate_path);
 | 
			
		||||
                errdefer self.allocator.free(build_file_uri);
 | 
			
		||||
 | 
			
		||||
                const build_file_handle = try self.newDocument(build_file_uri, build_file_text);
 | 
			
		||||
 | 
			
		||||
                if (build_file_handle.is_build_file) |build_file| {
 | 
			
		||||
                    build_file.refs += 1;
 | 
			
		||||
                if (candidate) |candidate_build_file| {
 | 
			
		||||
                    // Check if it is the same as the current candidate we got from the existing build files.
 | 
			
		||||
                    // If it isn't, we need to read the file and make a new build file.
 | 
			
		||||
                    if (std.mem.eql(u8, candidate_build_file.uri, build_file_uri)) {
 | 
			
		||||
                        self.allocator.free(build_file_uri);
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                handle.associated_build_file = build_file_handle.is_build_file;
 | 
			
		||||
 | 
			
		||||
                // Read the build file, create a new document, set the candidate to the new build file.
 | 
			
		||||
                const build_file_text = try build_file.readToEndAlloc(self.allocator, std.math.maxInt(usize));
 | 
			
		||||
                errdefer self.allocator.free(build_file_text);
 | 
			
		||||
 | 
			
		||||
                const build_file_handle = try self.newDocument(build_file_uri, build_file_text);
 | 
			
		||||
                candidate = build_file_handle.is_build_file.?;
 | 
			
		||||
                break;
 | 
			
		||||
            } else break :associate_build_file;
 | 
			
		||||
            } else break;
 | 
			
		||||
        }
 | 
			
		||||
        // Finally, associate the candidate build file, if any, to the new document.
 | 
			
		||||
        if (candidate) |build_file| {
 | 
			
		||||
            build_file.refs += 1;
 | 
			
		||||
            handle.associated_build_file = build_file;
 | 
			
		||||
            log.debug("Associated build file `{s}` to document `{s}`", .{build_file.uri, handle.uri()});
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user