Fix Timber.nvim: Missing Plenary Dependency For Log Watcher

by Felix Dubois 60 views

Hey guys! πŸ‘‹ Let's dive into this bug report about timber.nvim, a cool Neovim plugin for logging. It seems there's a missing dependency that can cause some headaches, so let's break it down and see what's up.

Did you check docs and existing issues?

  • [x] I have read all the plugin docs
  • [x] I have searched the existing issues
  • [x] I have searched the existing issues of plugins related to this issue

The user has diligently checked the documentation and existing issues, which is always a great first step when encountering a bug! πŸ‘

Neovim version (nvim -v)

0.11.2

This bug report is for Neovim version 0.11.2. Knowing the version helps in pinpointing if the issue is specific to a particular release.

Operating system/version

Fedora Linux 42

The operating system is Fedora Linux 42. OS-specific issues can sometimes occur, so this information is crucial.

Describe the bug

Plenary.nvim as a Missing Dependency

In this section, we're going to discuss plenary.nvim as a missing optional dependency in timber.nvim. The main issue reported here is that the "Capture log output" feature in timber.nvim has a hidden dependency on Plenary, which isn't explicitly stated in the README or examples. This can lead to frustrating errors for users who haven't installed Plenary separately.

When the log_watcher is enabled (especially for the 'filesystem' source), Neovim throws a stacktrace because it can't find the plenary.job module. This module is part of the Plenary plugin, and timber.nvim needs it for some of its functionality. Specifically, the filesystem.lua script tries to require plenary.job, and if Plenary isn't installed, Lua can't find the module, leading to the error.

Here's the error message you might see:

Failed to run `config` for timber.nvim
...
...zy/timber.nvim/lua/timber/watcher/sources/filesystem.lua:1: module 'plenary.job' not found:
        no field package.preload['plenary.job']
        cache_loader: module 'plenary.job' not found
        cache_loader_lib: module 'plenary.job' not found
        no file './plenary/job.lua'
        no file '/usr/share/luajit-2.1/plenary/job.lua'
        no file '/usr/local/share/lua/5.1/plenary/job.lua'
        no file '/usr/local/share/lua/5.1/plenary/job/init.lua'
        no file '/usr/share/lua/5.1/plenary/job.lua'
        no file '/usr/share/lua/5.1/plenary/job/init.lua'
        no file './plenary/job.so'
        no file '/usr/local/lib/lua/5.1/plenary/job.so'
        no file '/usr/lib64/lua/5.1/plenary/job.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'
        no file './plenary.so'
        no file '/usr/local/lib/lua/5.1/plenary.so'
        no file '/usr/lib64/lua/5.1/plenary.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'

# stacktrace:
  - /timber.nvim/lua/timber/watcher/sources/filesystem.lua:1
  - /timber.nvim/lua/timber/watcher/sources.lua:35 _in_ **setup**
  - /timber.nvim/lua/timber/watcher.lua:41 _in_ **setup**
  - /timber.nvim/lua/timber.lua:24 _in_ **setup**

The good news is that installing Plenary resolves this issue. The user also points out that if you're using Telescope (another Neovim plugin), you likely already have Plenary installed, as Telescope depends on it. So, this issue primarily affects users who haven't explicitly installed Plenary or aren't using other plugins that depend on it.

Impact on Users

The absence of a clear dependency declaration for Plenary can lead to a poor user experience. Imagine setting up timber.nvim, enabling the log watcher, and then being greeted by a scary-looking stacktrace! This can be especially confusing for new users who might not immediately understand the root cause.

The fact that Telescope, another popular Neovim plugin, also depends on Plenary adds an interesting twist. Many users might have Plenary installed already without realizing it, because they're using Telescope. This means the bug might not be immediately apparent for a significant portion of the user base. However, for those who don't use Telescope or other Plenary-dependent plugins, this issue is a definite roadblock.

Suggested Solution

The most straightforward solution is to explicitly declare Plenary as an optional dependency in timber.nvim's README. This could be as simple as adding a note in the installation section or in the documentation for the log_watcher feature. Something like:

Note: The `log_watcher` feature requires plenary.nvim. If you encounter errors related to missing `plenary.job`, please ensure you have plenary.nvim installed.

Alternatively, the plugin could be updated to lazily load the Plenary dependency. This means that the plugin would only attempt to require Plenary if the log_watcher feature is enabled. This would prevent the error from occurring for users who don't use this particular feature.

Importance of Clear Dependencies

This bug highlights the importance of clearly documenting dependencies in plugin development. Explicitly stating dependencies, whether they are required or optional, ensures a smoother installation and setup process for users. It also helps prevent unexpected errors and frustration.

In the Neovim ecosystem, where many plugins rely on each other, clear dependency management is crucial. Tools like plugin managers (e.g., Lazy, Packer) help automate the installation of dependencies, but it's still essential for plugin authors to provide accurate information about what their plugins need to function correctly.

Conclusion

The missing Plenary dependency in timber.nvim's "Capture log output" feature is a minor but important issue. By explicitly documenting this dependency, the plugin can provide a better experience for its users and prevent potential confusion. Whether through documentation updates or code changes, addressing this issue will make timber.nvim even more user-friendly.

Steps To Reproduce

The user provided a clear set of steps to reproduce the bug, which is super helpful! Here's the configuration they used with Lazy:

return {
   "Goose97/timber.nvim",
   version = "*", -- Use for stability; omit to use `main` branch for the latest features
   event = "VeryLazy",
   opts = {
      log_templates = {
         default = {
            go = [[log.Printf("%watcher_marker_start %log_target: %v %watcher_marker_end\n", %log_target)]]
         }
      },
      log_watcher = {
         enabled = true,
         -- A table of source id and source configuration
         sources = {
            log_file = {
               type = "filesystem",
               name = "Log file",
               path = "/tmp/debug.log",
            }
         }
      }
   }
}

With this configuration, enabling the log_watcher with a filesystem source will trigger the error if Plenary isn't installed.

Code Configuration Analysis

Let's break down the provided Lua code snippet to understand how timber.nvim is configured and how the issue arises. This analysis can help us pinpoint the exact conditions that trigger the bug and why it manifests.

  1. Plugin Declaration: The code starts by declaring the timber.nvim plugin within a Lazy configuration table.

    return {
       "Goose97/timber.nvim",
       version = "*", -- Use for stability; omit to use `main` branch for the latest features
       event = "VeryLazy",
       opts = { ... }
    }
    
    • "Goose97/timber.nvim": This specifies the plugin's repository on GitHub.
    • version = "*": This indicates that the plugin should use a stable version. Omitting this would default to the main branch, which might include the latest, potentially unstable, features.
    • event = "VeryLazy": This tells Lazy to load the plugin very late in the Neovim startup process, which is a common practice to improve startup time.
    • opts = { ... }: This is where the plugin's options are configured.
  2. Plugin Options: The opts table configures various aspects of timber.nvim, including log templates and the log watcher.

    opts = {
       log_templates = { ... },
       log_watcher = { ... }
    }
    
    • log_templates: This section defines how log messages should be formatted. The default template specifies how Go log messages should be structured, including markers for the watcher and the log target.

      log_templates = {
         default = {
            go = [[log.Printf("%watcher_marker_start %log_target: %v %watcher_marker_end\n", %log_target)]]
         }
      }
      
    • log_watcher: This is the key section for the bug report. It configures the log watching feature, which is where the dependency on Plenary arises.

      log_watcher = {
         enabled = true,
         sources = { ... }
      }
      
      • enabled = true: This enables the log watcher.

      • sources: This table defines the sources from which logs will be watched. In this case, there is a single source named log_file.

        sources = {
           log_file = {
              type = "filesystem",
              name = "Log file",
              path = "/tmp/debug.log",
           }
        }
        
        • type = "filesystem": This specifies that the log source is a file on the filesystem. This is where the Plenary dependency comes into play, as the filesystem watcher uses Plenary's job management capabilities.
        • name = "Log file": A descriptive name for the log source.
        • path = "/tmp/debug.log": The path to the log file being watched.
  3. Root Cause Analysis: The issue occurs because the filesystem log source type in timber.nvim relies on plenary.job to monitor file changes. However, plenary.job is part of the Plenary plugin, which is not explicitly declared as a dependency for timber.nvim. When the log_watcher is enabled with a filesystem source, timber.nvim attempts to require plenary.job, leading to a module not found error if Plenary is not installed.

Key Takeaways

  • The configuration clearly enables the log_watcher with a filesystem source.
  • The filesystem source type internally uses plenary.job from the Plenary plugin.
  • The lack of an explicit dependency declaration for Plenary causes the error.
  • Users who do not have Plenary installed (either directly or as a dependency of another plugin like Telescope) will encounter this issue.

Expected Behavior

Neovim should start without showing the previously mentioned error. Makes sense! No one likes seeing errors on startup. πŸ˜…

Hey everyone! πŸ‘‹ We've got a bug report here about timber.nvim, a super handy Neovim plugin, and it's all about a missing dependency. Specifically, the "Capture log output" feature needs Plenary, but it's not mentioned in the docs. Let's dive into the details and see how we can fix this!

What's the Issue? πŸ€”

So, the problem is that timber.nvim's log watcher, which is awesome for keeping an eye on your logs, uses Plenary behind the scenes. But, if you don't have Plenary installed, you'll get a nasty error message when you fire up Neovim. 😱

The Error Message

Here's the kind of stacktrace you might see:

Failed to run `config` for timber.nvim
...
...zy/timber.nvim/lua/timber/watcher/sources/filesystem.lua:1: module 'plenary.job' not found:
        no field package.preload['plenary.job']
        cache_loader: module 'plenary.job' not found
        cache_loader_lib: module 'plenary.job' not found
        no file './plenary/job.lua'
        no file '/usr/share/luajit-2.1/plenary/job.lua'
        no file '/usr/local/share/lua/5.1/plenary/job.lua'
        no file '/usr/local/share/lua/5.1/plenary/job/init.lua'
        no file '/usr/share/lua/5.1/plenary/job.lua'
        no file '/usr/share/lua/5.1/plenary/job/init.lua'
        no file './plenary/job.so'
        no file '/usr/local/lib/lua/5.1/plenary/job.so'
        no file '/usr/lib64/lua/5.1/plenary/job.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'
        no file './plenary.so'
        no file '/usr/local/lib/lua/5.1/plenary.so'
        no file '/usr/lib64/lua/5.1/plenary.so'
        no file '/usr/local/lib/lua/5.1/loadall.so'

# stacktrace:
  - /timber.nvim/lua/timber/watcher/sources/filesystem.lua:1
  - /timber.nvim/lua/timber/watcher/sources.lua:35 _in_ **setup**
  - /timber.nvim/lua/timber/watcher.lua:41 _in_ **setup**
  - /timber.nvim/lua/timber.lua:24 _in_ **setup**

This basically means that timber.nvim is trying to use Plenary's job module, but it can't find it. 😫

Why is this happening? πŸ€”

The core of the issue lies in the way timber.nvim handles its dependencies. timber.nvim uses Plenary, specifically the plenary.job module, for its filesystem log watching capabilities. When the log_watcher feature is enabled, particularly with the filesystem source type, timber.nvim attempts to load plenary.job. If Plenary is not installed, the require call fails, leading to the dreaded "module 'plenary.job' not found" error.

Optional vs. Required Dependencies

In software development, dependencies can be classified as either required or optional. A required dependency is essential for the software to function at all. If a required dependency is missing, the software simply won't work. An optional dependency, on the other hand, is only needed for certain features or functionalities. The software can still run without it, but some features might be disabled or limited.

In the case of timber.nvim, Plenary is an optional dependency. The core functionalities of timber.nvim, such as log formatting and display, do not depend on Plenary. It's only when the log_watcher is enabled with the filesystem source that Plenary becomes necessary.

The Importance of Explicit Declarations

The problem arises because timber.nvim doesn't explicitly declare Plenary as an optional dependency. This means that users who enable the log_watcher feature without knowing about the Plenary dependency will encounter the error. This can lead to confusion and frustration, especially for users who are new to Neovim or plugin management.

Explicitly declaring dependencies is a best practice in software development. It ensures that users are aware of the requirements for using a particular piece of software and can take the necessary steps to install those dependencies. This leads to a smoother and more predictable user experience.

The Role of Plugin Managers

Neovim plugin managers like Lazy and Packer play a crucial role in managing dependencies. These tools can automatically install dependencies based on information provided by the plugin. However, plugin managers can only do their job if the dependencies are correctly declared in the plugin's configuration or documentation.

If a plugin fails to declare a dependency, the plugin manager won't know to install it, and users will have to manually install the dependency themselves. This can be a hassle and can lead to errors if users are not aware of the dependency in the first place.

The Telescope Connection

The bug report also mentions an interesting connection to Telescope, another popular Neovim plugin. Telescope depends on Plenary, so users who have Telescope installed are likely to have Plenary installed as well. This means that the bug might not be immediately apparent to a significant number of timber.nvim users.

However, this doesn't negate the need to explicitly declare Plenary as a dependency. Users who don't use Telescope or other Plenary-dependent plugins will still encounter the issue. Additionally, relying on users having a transitive dependency (a dependency of a dependency) is generally not a good practice. It's always better to explicitly declare all dependencies, even if some users might already have them installed.

Potential Solutions

There are several ways to address this issue, which we'll dive into in the next section.

How to Fix It? πŸ› οΈ

There are a couple of ways to tackle this. The easiest is to add Plenary as an optional dependency in timber.nvim's documentation. This way, people know they need it if they want to use the log watcher. πŸ€“

Another way is to lazily load the Plenary dependency in the code. This means timber.nvim would only try to load Plenary if the log watcher is actually enabled. This is a bit more complex, but it's a cleaner solution. ✨

Lazy Loading

Lazy loading is a powerful technique in software development that can improve performance and reduce resource consumption. It involves delaying the loading of a resource (such as a module or a dependency) until it is actually needed.

In the context of timber.nvim, lazy loading would mean that the plugin would not attempt to load the plenary.job module until the log_watcher is enabled and the filesystem source is being used. This would prevent the error from occurring for users who don't use the log watcher or who use a different log source.

Lazy loading can be implemented using Lua's require function in conjunction with conditional checks. The plugin could check if the log_watcher is enabled and if the source type is filesystem before attempting to load plenary.job. This ensures that plenary.job is only loaded when it is actually needed.

Benefits of Lazy Loading

  • Improved Performance: Lazy loading can reduce startup time by delaying the loading of unnecessary modules. This is especially important for plugins that have many dependencies.
  • Reduced Resource Consumption: Lazy loading can reduce memory usage by only loading modules that are actively being used.
  • Cleaner Code: Lazy loading can make code cleaner and more modular by separating the loading of dependencies from the core logic of the plugin.

Documentation Update

Updating the documentation is a crucial step in addressing this issue. The documentation should clearly state that Plenary is an optional dependency for the log_watcher feature, especially when using the filesystem source. This will help users avoid the error and ensure a smoother experience.

The documentation update could include a note in the installation section or in the documentation for the log_watcher feature. The note should explain that Plenary is required for the filesystem log source and provide instructions on how to install it.

Example Documentation Note

Here's an example of a documentation note that could be added:

Note: The `log_watcher` feature requires plenary.nvim when using the `filesystem` source. If you encounter errors related to missing `plenary.job`, please ensure you have plenary.nvim installed.

This note is clear, concise, and provides the necessary information for users to resolve the issue.

How to Reproduce the Bug? πŸ›

The user provided a config snippet that makes it super easy to reproduce the bug. If you set up timber.nvim with the log_watcher enabled and a filesystem source, you'll likely see the error if you don't have Plenary installed. πŸ“

Expected Behavior βœ…

Of course, we want Neovim to start without any errors! That's the goal, right? πŸ˜‰

In Conclusion πŸŽ‰

This is a minor but important bug in timber.nvim. By making Plenary an explicit dependency (either in the docs or the code), we can make the plugin even better and prevent headaches for users. Thanks to the user who reported this! πŸ™ Let's get this fixed! πŸš€

Keep coding, keep logging, and keep those dependencies in check! πŸ’»πŸͺ΅βœ