Fix Timber.nvim: Missing Plenary Dependency For Log Watcher
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.
-
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 themain
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.
-
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. Thedefault
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 namedlog_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.
-
-
-
Root Cause Analysis: The issue occurs because the
filesystem
log source type intimber.nvim
relies onplenary.job
to monitor file changes. However,plenary.job
is part of the Plenary plugin, which is not explicitly declared as a dependency fortimber.nvim
. When thelog_watcher
is enabled with afilesystem
source,timber.nvim
attempts to requireplenary.job
, leading to a module not found error if Plenary is not installed.
Key Takeaways
- The configuration clearly enables the
log_watcher
with afilesystem
source. - The
filesystem
source type internally usesplenary.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! π»πͺ΅β