Skip to content

Commit

Permalink
feat(cli): better environment variables (#3621)
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico authored Aug 9, 2024
1 parent 7f65eda commit 3685b29
Show file tree
Hide file tree
Showing 25 changed files with 481 additions and 183 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b

Contributed by @NiclasvanEyk

- Add new options to the `lsp-proxy` and `start` commands:
- `--log-path`: a directory where to store the daemon logs. The commands also accepts the environment variable `BIOME_LOG_PATH`.
- `--log-prefix-name`: a prefix that's added to the file name of the logs. It defaults to `server.log`. The commands also accepts the environment variable `BIOME_LOG_PREFIX_NAME`.

@Contributed by @ematipico


#### Enhancements

- When a `--reporter` is provided, and it's different from the default one, the value provided by via `--max-diagnostics` is ignored and **the limit is lifted**. Contributed by @ematipico
Expand Down
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/biome_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ biome_console = { workspace = true }
biome_deserialize = { workspace = true }
biome_deserialize_macros = { workspace = true }
biome_diagnostics = { workspace = true }
biome_flags = { workspace = true }
biome_formatter = { workspace = true }
biome_fs = { workspace = true }
biome_js_analyze = { workspace = true }
Expand Down
11 changes: 8 additions & 3 deletions crates/biome_cli/src/commands/clean.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use crate::commands::daemon::biome_log_dir;
use crate::commands::daemon::default_biome_log_path;
use crate::{CliDiagnostic, CliSession};
use biome_flags::biome_env;
use std::fs::{create_dir, remove_dir_all};
use std::path::PathBuf;

/// Runs the clean command
pub fn clean(_cli_session: CliSession) -> Result<(), CliDiagnostic> {
let logs_dir = biome_log_dir();
remove_dir_all(logs_dir.clone()).and_then(|_| create_dir(logs_dir))?;
let logs_path = biome_env()
.biome_log_path
.value()
.map_or(default_biome_log_path(), PathBuf::from);
remove_dir_all(logs_path.clone()).and_then(|_| create_dir(logs_path))?;
Ok(())
}
71 changes: 51 additions & 20 deletions crates/biome_cli/src/commands/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,16 @@ use tracing_tree::HierarchicalLayer;
pub(crate) fn start(
session: CliSession,
config_path: Option<PathBuf>,
log_path: Option<PathBuf>,
log_file_name_prefix: Option<String>,
) -> Result<(), CliDiagnostic> {
let rt = Runtime::new()?;
let did_spawn = rt.block_on(ensure_daemon(false, config_path))?;
let did_spawn = rt.block_on(ensure_daemon(
false,
config_path,
log_path,
log_file_name_prefix,
))?;

if did_spawn {
session.app.console.log(markup! {
Expand Down Expand Up @@ -65,8 +72,10 @@ pub(crate) fn stop(session: CliSession) -> Result<(), CliDiagnostic> {
pub(crate) fn run_server(
stop_on_disconnect: bool,
config_path: Option<PathBuf>,
log_path: Option<PathBuf>,
log_file_name_prefix: Option<String>,
) -> Result<(), CliDiagnostic> {
setup_tracing_subscriber();
setup_tracing_subscriber(log_path, log_file_name_prefix);

let rt = Runtime::new()?;
let factory = ServerFactory::new(stop_on_disconnect);
Expand Down Expand Up @@ -95,18 +104,32 @@ pub(crate) fn print_socket() -> Result<(), CliDiagnostic> {
Ok(())
}

pub(crate) fn lsp_proxy(config_path: Option<PathBuf>) -> Result<(), CliDiagnostic> {
pub(crate) fn lsp_proxy(
config_path: Option<PathBuf>,
log_path: Option<PathBuf>,
log_file_name_prefix: Option<String>,
) -> Result<(), CliDiagnostic> {
let rt = Runtime::new()?;
rt.block_on(start_lsp_proxy(&rt, config_path))?;
rt.block_on(start_lsp_proxy(
&rt,
config_path,
log_path,
log_file_name_prefix,
))?;

Ok(())
}

/// Start a proxy process.
/// Receives a process via `stdin` and then copy the content to the LSP socket.
/// Copy to the process on `stdout` when the LSP responds to a message
async fn start_lsp_proxy(rt: &Runtime, config_path: Option<PathBuf>) -> Result<(), CliDiagnostic> {
ensure_daemon(true, config_path).await?;
async fn start_lsp_proxy(
rt: &Runtime,
config_path: Option<PathBuf>,
log_path: Option<PathBuf>,
log_file_name_prefix: Option<String>,
) -> Result<(), CliDiagnostic> {
ensure_daemon(true, config_path, log_path, log_file_name_prefix).await?;

match open_socket().await? {
Some((mut owned_read_half, mut owned_write_half)) => {
Expand Down Expand Up @@ -148,21 +171,20 @@ async fn start_lsp_proxy(rt: &Runtime, config_path: Option<PathBuf>) -> Result<(
}
}

const fn log_file_name_prefix() -> &'static str {
"server.log"
}

pub(crate) fn read_most_recent_log_file() -> io::Result<Option<String>> {
let logs_dir = biome_log_dir();
pub(crate) fn read_most_recent_log_file(
log_path: Option<PathBuf>,
log_file_name_prefix: String,
) -> io::Result<Option<String>> {
let biome_log_path = log_path.unwrap_or(default_biome_log_path());

let most_recent = fs::read_dir(logs_dir)?
let most_recent = fs::read_dir(biome_log_path)?
.flatten()
.filter(|file| file.file_type().map_or(false, |ty| ty.is_file()))
.filter_map(|file| {
match file
.file_name()
.to_str()?
.split_once(log_file_name_prefix())
.split_once(log_file_name_prefix.as_str())
{
Some((_, date_part)) if date_part.split('-').count() == 4 => Some(file.path()),
_ => None,
Expand All @@ -176,14 +198,19 @@ pub(crate) fn read_most_recent_log_file() -> io::Result<Option<String>> {
}
}

/// Setup the [tracing]-based logging system for the server
/// Set up the [tracing]-based logging system for the server
/// The events received by the subscriber are filtered at the `info` level,
/// then printed using the [HierarchicalLayer] layer, and the resulting text
/// is written to log files rotated on a hourly basis (in
/// `biome-logs/server.log.yyyy-MM-dd-HH` files inside the system temporary
/// directory)
fn setup_tracing_subscriber() {
let file_appender = tracing_appender::rolling::hourly(biome_log_dir(), log_file_name_prefix());
fn setup_tracing_subscriber(log_path: Option<PathBuf>, log_file_name_prefix: Option<String>) {
let biome_log_path = log_path.unwrap_or(biome_fs::ensure_cache_dir().join("biome-logs"));
let file_appender = tracing_appender::rolling::hourly(
biome_log_path,
// The `Option` is required because we have a command called __print-socket that spans a daemon only to retrieve its port
log_file_name_prefix.unwrap_or(String::from("server.log")),
);

registry()
.with(
Expand All @@ -199,10 +226,14 @@ fn setup_tracing_subscriber() {
.init();
}

pub fn biome_log_dir() -> PathBuf {
match env::var_os("BIOME_LOG_DIR") {
pub fn default_biome_log_path() -> PathBuf {
match env::var_os("BIOME_LOG_PATH") {
Some(directory) => PathBuf::from(directory),
None => biome_fs::ensure_cache_dir().join("biome-logs"),
// TODO: Remove in Biome v2, and use the None part as fallback.
None => match env::var_os("BIOME_LOG_DIR") {
Some(directory) => PathBuf::from(directory),
None => biome_fs::ensure_cache_dir().join("biome-logs"),
},
}
}

Expand Down
8 changes: 6 additions & 2 deletions crates/biome_cli/src/commands/explain.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use biome_analyze::{FixKind, RuleMetadata};
use biome_console::{markup, ConsoleExt};
use biome_flags::biome_env;
use biome_service::documentation::Doc;

use crate::commands::daemon::biome_log_dir;
use crate::commands::daemon::default_biome_log_path;
use crate::{CliDiagnostic, CliSession};

fn print_rule(session: CliSession, metadata: &RuleMetadata) {
Expand Down Expand Up @@ -45,7 +46,10 @@ pub(crate) fn explain(session: CliSession, doc: Doc) -> Result<(), CliDiagnostic
Ok(())
}
Doc::DaemonLogs => {
let cache_dir = biome_log_dir().display().to_string();
let cache_dir = biome_env()
.biome_log_path
.value()
.unwrap_or(default_biome_log_path().display().to_string());
session.app.console.error(markup! {
<Info>"The daemon logs are available in the directory: \n"</Info>
});
Expand Down
81 changes: 70 additions & 11 deletions crates/biome_cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,41 @@ pub enum BiomeCommand {
/// Prints the Biome daemon server logs
#[bpaf(long("daemon-logs"), switch)]
bool,
/// Prints the Biome configuration that the applied formatter configuration
/// Prints the formatter options applied
#[bpaf(long("formatter"), switch)]
bool,
/// Prints the Biome configuration that the applied linter configuration
/// Prints the linter options applied
#[bpaf(long("linter"), switch)]
bool,
),
/// Start the Biome daemon server process
#[bpaf(command)]
Start(
Start {
/// Allows to change the prefix applied to the file name of the logs.
#[bpaf(
env("BIOME_LOG_PREFIX_NAME"),
long("log-prefix-name"),
argument("STRING"),
hide_usage,
fallback(String::from("server.log")),
display_fallback
)]
log_prefix_name: String,

/// Allows to change the folder where logs are stored.
#[bpaf(
env("BIOME_LOG_PATH"),
long("log-path"),
argument("PATH"),
hide_usage,
fallback(biome_fs::ensure_cache_dir().join("biome-logs")),
)]
log_path: PathBuf,
/// Allows to set a custom file path to the configuration file,
/// or a custom directory path to find `biome.json` or `biome.jsonc`
#[bpaf(env("BIOME_CONFIG_PATH"), long("config-path"), argument("PATH"))]
Option<PathBuf>,
),
config_path: Option<PathBuf>,
},

/// Stop the Biome daemon server process
#[bpaf(command)]
Expand Down Expand Up @@ -350,15 +370,34 @@ pub enum BiomeCommand {
),
/// Acts as a server for the Language Server Protocol over stdin/stdout
#[bpaf(command("lsp-proxy"))]
LspProxy(
LspProxy {
/// Allows to change the prefix applied to the file name of the logs.
#[bpaf(
env("BIOME_LOG_PREFIX_NAME"),
long("log-prefix-name"),
argument("STRING"),
hide_usage,
fallback(String::from("server.log")),
display_fallback
)]
log_prefix_name: String,
/// Allows to change the folder where logs are stored.
#[bpaf(
env("BIOME_LOG_PATH"),
long("log-path"),
argument("PATH"),
hide_usage,
fallback(biome_fs::ensure_cache_dir().join("biome-logs")),
)]
log_path: PathBuf,
/// Allows to set a custom file path to the configuration file,
/// or a custom directory path to find `biome.json` or `biome.jsonc`
#[bpaf(env("BIOME_CONFIG_PATH"), long("config-path"), argument("PATH"))]
Option<PathBuf>,
config_path: Option<PathBuf>,
/// Bogus argument to make the command work with vscode-languageclient
#[bpaf(long("stdio"), hide, hide_usage, switch)]
bool,
),
stdio: bool,
},
/// It updates the configuration when there are breaking changes
#[bpaf(command)]
Migrate {
Expand Down Expand Up @@ -435,6 +474,26 @@ pub enum BiomeCommand {

#[bpaf(command("__run_server"), hide)]
RunServer {
/// Allows to change the prefix applied to the file name of the logs.
#[bpaf(
env("BIOME_LOG_PREFIX_NAME"),
long("log-prefix-name"),
argument("STRING"),
hide_usage,
fallback(String::from("server.log")),
display_fallback
)]
log_prefix_name: String,
/// Allows to change the folder where logs are stored.
#[bpaf(
env("BIOME_LOG_PATH"),
long("log-path"),
argument("PATH"),
hide_usage,
fallback(biome_fs::ensure_cache_dir().join("biome-logs")),
)]
log_path: PathBuf,

#[bpaf(long("stop-on-disconnect"), hide_usage)]
stop_on_disconnect: bool,
/// Allows to set a custom file path to the configuration file,
Expand Down Expand Up @@ -480,8 +539,8 @@ impl BiomeCommand {
| BiomeCommand::Format { cli_options, .. }
| BiomeCommand::Migrate { cli_options, .. }
| BiomeCommand::Search { cli_options, .. } => Some(cli_options),
BiomeCommand::LspProxy(_, _)
| BiomeCommand::Start(_)
BiomeCommand::LspProxy { .. }
| BiomeCommand::Start { .. }
| BiomeCommand::Stop
| BiomeCommand::Init(_)
| BiomeCommand::Explain { .. }
Expand Down
Loading

0 comments on commit 3685b29

Please sign in to comment.