mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 22:01:18 +00:00
Auto-generate environment variable references for ty (#19205)
## Summary
This PR mirrors the environment variable implementation we have in uv:
efc361223c/crates/uv-static/src/env_vars.rs (L6-L7)
.
See: https://github.com/astral-sh/ty/issues/773.
This commit is contained in:
parent
149350bf39
commit
3ee3434187
24 changed files with 458 additions and 14 deletions
|
@ -6,7 +6,7 @@ exclude: |
|
|||
crates/ty_vendored/vendor/.*|
|
||||
crates/ty_project/resources/.*|
|
||||
crates/ty_python_semantic/resources/corpus/.*|
|
||||
crates/ty/docs/(configuration|rules|cli).md|
|
||||
crates/ty/docs/(configuration|rules|cli|environment).md|
|
||||
crates/ruff_benchmark/resources/.*|
|
||||
crates/ruff_linter/resources/.*|
|
||||
crates/ruff_linter/src/rules/.*/snapshots/.*|
|
||||
|
|
21
Cargo.lock
generated
21
Cargo.lock
generated
|
@ -2874,6 +2874,7 @@ dependencies = [
|
|||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"ty_static",
|
||||
"web-time",
|
||||
"zip",
|
||||
]
|
||||
|
@ -2917,6 +2918,7 @@ dependencies = [
|
|||
"tracing-subscriber",
|
||||
"ty",
|
||||
"ty_project",
|
||||
"ty_static",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -4165,6 +4167,7 @@ dependencies = [
|
|||
"ty_project",
|
||||
"ty_python_semantic",
|
||||
"ty_server",
|
||||
"ty_static",
|
||||
"wild",
|
||||
]
|
||||
|
||||
|
@ -4186,6 +4189,15 @@ dependencies = [
|
|||
"ty_vendored",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ty_macros"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ty_project"
|
||||
version = "0.0.0"
|
||||
|
@ -4268,6 +4280,7 @@ dependencies = [
|
|||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
"ty_python_semantic",
|
||||
"ty_static",
|
||||
"ty_test",
|
||||
"ty_vendored",
|
||||
]
|
||||
|
@ -4299,6 +4312,13 @@ dependencies = [
|
|||
"ty_vendored",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ty_static"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"ty_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ty_test"
|
||||
version = "0.0.0"
|
||||
|
@ -4327,6 +4347,7 @@ dependencies = [
|
|||
"toml",
|
||||
"tracing",
|
||||
"ty_python_semantic",
|
||||
"ty_static",
|
||||
"ty_vendored",
|
||||
]
|
||||
|
||||
|
|
|
@ -41,9 +41,11 @@ ruff_workspace = { path = "crates/ruff_workspace" }
|
|||
|
||||
ty = { path = "crates/ty" }
|
||||
ty_ide = { path = "crates/ty_ide" }
|
||||
ty_macros = { path = "crates/ty_macros" }
|
||||
ty_project = { path = "crates/ty_project", default-features = false }
|
||||
ty_python_semantic = { path = "crates/ty_python_semantic" }
|
||||
ty_server = { path = "crates/ty_server" }
|
||||
ty_static = { path = "crates/ty_static" }
|
||||
ty_test = { path = "crates/ty_test" }
|
||||
ty_vendored = { path = "crates/ty_vendored" }
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ ruff_python_parser = { workspace = true }
|
|||
ruff_python_trivia = { workspace = true }
|
||||
ruff_source_file = { workspace = true, features = ["get-size"] }
|
||||
ruff_text_size = { workspace = true }
|
||||
ty_static = { workspace = true }
|
||||
|
||||
anstyle = { workspace = true }
|
||||
arc-swap = { workspace = true }
|
||||
|
|
|
@ -5,6 +5,7 @@ use ruff_python_ast::PythonVersion;
|
|||
use rustc_hash::FxHasher;
|
||||
use std::hash::BuildHasherDefault;
|
||||
use std::num::NonZeroUsize;
|
||||
use ty_static::EnvVars;
|
||||
|
||||
pub mod diagnostic;
|
||||
pub mod display;
|
||||
|
@ -50,8 +51,8 @@ pub trait Db: salsa::Database {
|
|||
/// ty can still spawn more threads for other tasks, e.g. to wait for a Ctrl+C signal or
|
||||
/// watching the files for changes.
|
||||
pub fn max_parallelism() -> NonZeroUsize {
|
||||
std::env::var("TY_MAX_PARALLELISM")
|
||||
.or_else(|_| std::env::var("RAYON_NUM_THREADS"))
|
||||
std::env::var(EnvVars::TY_MAX_PARALLELISM)
|
||||
.or_else(|_| std::env::var(EnvVars::RAYON_NUM_THREADS))
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or_else(|| {
|
||||
|
|
|
@ -13,6 +13,7 @@ license = { workspace = true }
|
|||
[dependencies]
|
||||
ty = { workspace = true }
|
||||
ty_project = { workspace = true, features = ["schemars"] }
|
||||
ty_static = { workspace = true }
|
||||
ruff = { workspace = true }
|
||||
ruff_formatter = { workspace = true }
|
||||
ruff_linter = { workspace = true, features = ["schemars"] }
|
||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
|||
|
||||
use crate::{
|
||||
generate_cli_help, generate_docs, generate_json_schema, generate_ty_cli_reference,
|
||||
generate_ty_options, generate_ty_rules, generate_ty_schema,
|
||||
generate_ty_env_vars_reference, generate_ty_options, generate_ty_rules, generate_ty_schema,
|
||||
};
|
||||
|
||||
pub(crate) const REGENERATE_ALL_COMMAND: &str = "cargo dev generate-all";
|
||||
|
@ -44,5 +44,8 @@ pub(crate) fn main(args: &Args) -> Result<()> {
|
|||
generate_ty_options::main(&generate_ty_options::Args { mode: args.mode })?;
|
||||
generate_ty_rules::main(&generate_ty_rules::Args { mode: args.mode })?;
|
||||
generate_ty_cli_reference::main(&generate_ty_cli_reference::Args { mode: args.mode })?;
|
||||
generate_ty_env_vars_reference::main(&generate_ty_env_vars_reference::Args {
|
||||
mode: args.mode,
|
||||
})?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
119
crates/ruff_dev/src/generate_ty_env_vars_reference.rs
Normal file
119
crates/ruff_dev/src/generate_ty_env_vars_reference.rs
Normal file
|
@ -0,0 +1,119 @@
|
|||
//! Generate the environment variables reference from `ty_static::EnvVars`.
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::bail;
|
||||
use pretty_assertions::StrComparison;
|
||||
|
||||
use ty_static::EnvVars;
|
||||
|
||||
use crate::generate_all::Mode;
|
||||
|
||||
#[derive(clap::Args)]
|
||||
pub(crate) struct Args {
|
||||
#[arg(long, default_value_t, value_enum)]
|
||||
pub(crate) mode: Mode,
|
||||
}
|
||||
|
||||
pub(crate) fn main(args: &Args) -> anyhow::Result<()> {
|
||||
let reference_string = generate();
|
||||
let filename = "environment.md";
|
||||
let reference_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.parent()
|
||||
.unwrap()
|
||||
.parent()
|
||||
.unwrap()
|
||||
.join("crates")
|
||||
.join("ty")
|
||||
.join("docs")
|
||||
.join(filename);
|
||||
|
||||
match args.mode {
|
||||
Mode::DryRun => {
|
||||
println!("{reference_string}");
|
||||
}
|
||||
Mode::Check => match fs::read_to_string(&reference_path) {
|
||||
Ok(current) => {
|
||||
if current == reference_string {
|
||||
println!("Up-to-date: {filename}");
|
||||
} else {
|
||||
let comparison = StrComparison::new(¤t, &reference_string);
|
||||
bail!(
|
||||
"{filename} changed, please run `cargo dev generate-ty-env-vars-reference`:\n{comparison}"
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
bail!(
|
||||
"{filename} not found, please run `cargo dev generate-ty-env-vars-reference`"
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
bail!(
|
||||
"{filename} changed, please run `cargo dev generate-ty-env-vars-reference`:\n{err}"
|
||||
);
|
||||
}
|
||||
},
|
||||
Mode::Write => {
|
||||
// Ensure the docs directory exists
|
||||
if let Some(parent) = reference_path.parent() {
|
||||
fs::create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
match fs::read_to_string(&reference_path) {
|
||||
Ok(current) => {
|
||||
if current == reference_string {
|
||||
println!("Up-to-date: {filename}");
|
||||
} else {
|
||||
println!("Updating: {filename}");
|
||||
fs::write(&reference_path, reference_string.as_bytes())?;
|
||||
}
|
||||
}
|
||||
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||
println!("Updating: {filename}");
|
||||
fs::write(&reference_path, reference_string.as_bytes())?;
|
||||
}
|
||||
Err(err) => {
|
||||
bail!(
|
||||
"{filename} changed, please run `cargo dev generate-ty-env-vars-reference`:\n{err}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate() -> String {
|
||||
let mut output = String::new();
|
||||
|
||||
output.push_str("# Environment variables\n\n");
|
||||
|
||||
// Partition and sort environment variables into TY_ and external variables.
|
||||
let (ty_vars, external_vars): (BTreeSet<_>, BTreeSet<_>) = EnvVars::metadata()
|
||||
.iter()
|
||||
.partition(|(var, _)| var.starts_with("TY_"));
|
||||
|
||||
output.push_str("ty defines and respects the following environment variables:\n\n");
|
||||
|
||||
for (var, doc) in ty_vars {
|
||||
output.push_str(&render(var, doc));
|
||||
}
|
||||
|
||||
output.push_str("## Externally-defined variables\n\n");
|
||||
output.push_str("ty also reads the following externally defined environment variables:\n\n");
|
||||
|
||||
for (var, doc) in external_vars {
|
||||
output.push_str(&render(var, doc));
|
||||
}
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
/// Render an environment variable and its documentation.
|
||||
fn render(var: &str, doc: &str) -> String {
|
||||
format!("### `{var}`\n\n{doc}\n\n")
|
||||
}
|
|
@ -18,6 +18,7 @@ mod generate_json_schema;
|
|||
mod generate_options;
|
||||
mod generate_rules_table;
|
||||
mod generate_ty_cli_reference;
|
||||
mod generate_ty_env_vars_reference;
|
||||
mod generate_ty_options;
|
||||
mod generate_ty_rules;
|
||||
mod generate_ty_schema;
|
||||
|
@ -53,6 +54,8 @@ enum Command {
|
|||
/// Generate a Markdown-compatible listing of configuration options.
|
||||
GenerateOptions,
|
||||
GenerateTyOptions(generate_ty_options::Args),
|
||||
/// Generate environment variables reference for ty.
|
||||
GenerateTyEnvVarsReference(generate_ty_env_vars_reference::Args),
|
||||
/// Generate CLI help.
|
||||
GenerateCliHelp(generate_cli_help::Args),
|
||||
/// Generate Markdown docs.
|
||||
|
@ -98,6 +101,7 @@ fn main() -> Result<ExitCode> {
|
|||
Command::GenerateTyRules(args) => generate_ty_rules::main(&args)?,
|
||||
Command::GenerateOptions => println!("{}", generate_options::generate()),
|
||||
Command::GenerateTyOptions(args) => generate_ty_options::main(&args)?,
|
||||
Command::GenerateTyEnvVarsReference(args) => generate_ty_env_vars_reference::main(&args)?,
|
||||
Command::GenerateCliHelp(args) => generate_cli_help::main(&args)?,
|
||||
Command::GenerateDocs(args) => generate_docs::main(&args)?,
|
||||
Command::PrintAST(args) => print_ast::main(&args)?,
|
||||
|
|
|
@ -19,6 +19,7 @@ ruff_python_ast = { workspace = true }
|
|||
ty_python_semantic = { workspace = true }
|
||||
ty_project = { workspace = true, features = ["zstd"] }
|
||||
ty_server = { workspace = true }
|
||||
ty_static = { workspace = true }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
argfile = { workspace = true }
|
||||
|
|
55
crates/ty/docs/environment.md
Normal file
55
crates/ty/docs/environment.md
Normal file
|
@ -0,0 +1,55 @@
|
|||
# Environment variables
|
||||
|
||||
ty defines and respects the following environment variables:
|
||||
|
||||
### `TY_LOG`
|
||||
|
||||
If set, ty will use this value as the log level for its `--verbose` output.
|
||||
Accepts any filter compatible with the `tracing_subscriber` crate.
|
||||
|
||||
For example:
|
||||
|
||||
- `TY_LOG=uv=debug` is the equivalent of `-vv` to the command line
|
||||
- `TY_LOG=trace` will enable all trace-level logging.
|
||||
|
||||
See the [tracing documentation](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#example-syntax)
|
||||
for more.
|
||||
|
||||
### `TY_LOG_PROFILE`
|
||||
|
||||
If set to `"1"` or `"true"`, ty will enable flamegraph profiling.
|
||||
This creates a `tracing.folded` file that can be used to generate flame graphs
|
||||
for performance analysis.
|
||||
|
||||
### `TY_MAX_PARALLELISM`
|
||||
|
||||
Specifies an upper limit for the number of tasks ty is allowed to run in parallel.
|
||||
|
||||
For example, how many files should be checked in parallel.
|
||||
This isn't the same as a thread limit. ty may spawn additional threads
|
||||
when necessary, e.g. to watch for file system changes or a dedicated UI thread.
|
||||
|
||||
## Externally-defined variables
|
||||
|
||||
ty also reads the following externally defined environment variables:
|
||||
|
||||
### `CONDA_PREFIX`
|
||||
|
||||
Used to detect an activated Conda environment location.
|
||||
If both `VIRTUAL_ENV` and `CONDA_PREFIX` are present, `VIRTUAL_ENV` will be preferred.
|
||||
|
||||
### `RAYON_NUM_THREADS`
|
||||
|
||||
Specifies an upper limit for the number of threads ty uses when performing work in parallel.
|
||||
Equivalent to `TY_MAX_PARALLELISM`.
|
||||
|
||||
This is a standard Rayon environment variable.
|
||||
|
||||
### `VIRTUAL_ENV`
|
||||
|
||||
Used to detect an activated virtual environment.
|
||||
|
||||
### `XDG_CONFIG_HOME`
|
||||
|
||||
Path to user-level configuration directory on Unix systems.
|
||||
|
|
@ -4,6 +4,7 @@ mod python_version;
|
|||
mod version;
|
||||
|
||||
pub use args::Cli;
|
||||
use ty_static::EnvVars;
|
||||
|
||||
use std::io::{self, BufWriter, Write, stdout};
|
||||
use std::process::{ExitCode, Termination};
|
||||
|
@ -144,7 +145,7 @@ fn run_check(args: CheckCommand) -> anyhow::Result<ExitStatus> {
|
|||
};
|
||||
|
||||
let mut stdout = stdout().lock();
|
||||
match std::env::var("TY_MEMORY_REPORT").as_deref() {
|
||||
match std::env::var(EnvVars::TY_MEMORY_REPORT).as_deref() {
|
||||
Ok("short") => write!(stdout, "{}", db.salsa_memory_dump().display_short())?,
|
||||
Ok("mypy_primer") => write!(stdout, "{}", db.salsa_memory_dump().display_mypy_primer())?,
|
||||
Ok("full") => write!(stdout, "{}", db.salsa_memory_dump().display_full())?,
|
||||
|
|
|
@ -12,6 +12,7 @@ use tracing_subscriber::filter::LevelFilter;
|
|||
use tracing_subscriber::fmt::format::Writer;
|
||||
use tracing_subscriber::fmt::{FmtContext, FormatEvent, FormatFields};
|
||||
use tracing_subscriber::registry::LookupSpan;
|
||||
use ty_static::EnvVars;
|
||||
|
||||
/// Logging flags to `#[command(flatten)]` into your CLI
|
||||
#[derive(clap::Args, Debug, Clone, Default)]
|
||||
|
@ -84,7 +85,7 @@ pub(crate) fn setup_tracing(
|
|||
use tracing_subscriber::prelude::*;
|
||||
|
||||
// The `TY_LOG` environment variable overrides the default log level.
|
||||
let filter = if let Ok(log_env_variable) = std::env::var("TY_LOG") {
|
||||
let filter = if let Ok(log_env_variable) = std::env::var(EnvVars::TY_LOG) {
|
||||
EnvFilter::builder()
|
||||
.parse(log_env_variable)
|
||||
.context("Failed to parse directives specified in TY_LOG environment variable.")?
|
||||
|
@ -165,7 +166,7 @@ fn setup_profile<S>() -> (
|
|||
where
|
||||
S: Subscriber + for<'span> LookupSpan<'span>,
|
||||
{
|
||||
if let Ok("1" | "true") = std::env::var("TY_LOG_PROFILE").as_deref() {
|
||||
if let Ok("1" | "true") = std::env::var(EnvVars::TY_LOG_PROFILE).as_deref() {
|
||||
let (layer, guard) = tracing_flame::FlameLayer::with_file("tracing.folded")
|
||||
.expect("Flame layer to be created");
|
||||
(Some(layer), Some(guard))
|
||||
|
|
21
crates/ty_macros/Cargo.toml
Normal file
21
crates/ty_macros/Cargo.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
[package]
|
||||
name = "ty_macros"
|
||||
version = "0.0.0"
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
documentation = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = { workspace = true }
|
||||
quote = { workspace = true }
|
||||
syn = { workspace = true }
|
95
crates/ty_macros/src/env_vars.rs
Normal file
95
crates/ty_macros/src/env_vars.rs
Normal file
|
@ -0,0 +1,95 @@
|
|||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{ImplItem, ItemImpl};
|
||||
|
||||
pub(crate) fn attribute_env_vars_metadata(mut input: ItemImpl) -> TokenStream {
|
||||
// Verify that this is an impl for EnvVars
|
||||
let impl_type = &input.self_ty;
|
||||
|
||||
let mut env_var_entries = Vec::new();
|
||||
let mut hidden_vars = Vec::new();
|
||||
|
||||
// Process each item in the impl block
|
||||
for item in &mut input.items {
|
||||
if let ImplItem::Const(const_item) = item {
|
||||
// Extract the const name and value
|
||||
let const_name = &const_item.ident;
|
||||
let const_expr = &const_item.expr;
|
||||
|
||||
// Check if the const has the #[attr_hidden] attribute
|
||||
let is_hidden = const_item
|
||||
.attrs
|
||||
.iter()
|
||||
.any(|attr| attr.path().is_ident("attr_hidden"));
|
||||
|
||||
// Remove our custom attributes
|
||||
const_item.attrs.retain(|attr| {
|
||||
!attr.path().is_ident("attr_hidden")
|
||||
&& !attr.path().is_ident("attr_env_var_pattern")
|
||||
});
|
||||
|
||||
if is_hidden {
|
||||
hidden_vars.push(const_name.clone());
|
||||
} else {
|
||||
// Extract documentation from doc comments
|
||||
let doc_attrs: Vec<_> = const_item
|
||||
.attrs
|
||||
.iter()
|
||||
.filter(|attr| attr.path().is_ident("doc"))
|
||||
.collect();
|
||||
|
||||
if !doc_attrs.is_empty() {
|
||||
// Convert doc attributes to a single string
|
||||
let doc_string = extract_doc_string(&doc_attrs);
|
||||
env_var_entries.push((const_name.clone(), const_expr.clone(), doc_string));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the metadata method.
|
||||
let metadata_entries: Vec<_> = env_var_entries
|
||||
.iter()
|
||||
.map(|(_name, expr, doc)| {
|
||||
quote! {
|
||||
(#expr, #doc)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let metadata_impl = quote! {
|
||||
impl #impl_type {
|
||||
/// Returns metadata for all non-hidden environment variables.
|
||||
pub fn metadata() -> Vec<(&'static str, &'static str)> {
|
||||
vec![
|
||||
#(#metadata_entries),*
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
quote! {
|
||||
#input
|
||||
#metadata_impl
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract documentation from doc attributes into a single string
|
||||
fn extract_doc_string(attrs: &[&syn::Attribute]) -> String {
|
||||
attrs
|
||||
.iter()
|
||||
.filter_map(|attr| {
|
||||
if let syn::Meta::NameValue(meta) = &attr.meta {
|
||||
if let syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Str(lit_str),
|
||||
..
|
||||
}) = &meta.value
|
||||
{
|
||||
return Some(lit_str.value().trim().to_string());
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
18
crates/ty_macros/src/lib.rs
Normal file
18
crates/ty_macros/src/lib.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
//! This crate implements internal macros for the `ty` library.
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use syn::parse_macro_input;
|
||||
|
||||
mod env_vars;
|
||||
|
||||
/// Generates metadata for environment variables declared in the impl block.
|
||||
///
|
||||
/// This attribute macro should be applied to an `impl EnvVars` block.
|
||||
/// It will generate a `metadata()` method that returns all non-hidden
|
||||
/// environment variables with their documentation.
|
||||
#[proc_macro_attribute]
|
||||
pub fn attribute_env_vars_metadata(_attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(item as syn::ItemImpl);
|
||||
|
||||
env_vars::attribute_env_vars_metadata(input).into()
|
||||
}
|
|
@ -22,6 +22,7 @@ ruff_source_file = { workspace = true }
|
|||
ruff_text_size = { workspace = true }
|
||||
ruff_python_literal = { workspace = true }
|
||||
ruff_python_trivia = { workspace = true }
|
||||
ty_static = { workspace = true }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
bitflags = { workspace = true }
|
||||
|
@ -52,6 +53,7 @@ strum_macros = { workspace = true }
|
|||
ruff_db = { workspace = true, features = ["testing", "os"] }
|
||||
ruff_python_parser = { workspace = true }
|
||||
ty_python_semantic = { workspace = true, features = ["testing"] }
|
||||
ty_static = { workspace = true }
|
||||
ty_test = { workspace = true }
|
||||
ty_vendored = { workspace = true }
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ use ruff_python_ast::PythonVersion;
|
|||
use ruff_python_trivia::Cursor;
|
||||
use ruff_source_file::{LineIndex, OneIndexed, SourceCode};
|
||||
use ruff_text_size::{TextLen, TextRange};
|
||||
use ty_static::EnvVars;
|
||||
|
||||
type SitePackagesDiscoveryResult<T> = Result<T, SitePackagesDiscoveryError>;
|
||||
|
||||
|
@ -149,7 +150,7 @@ impl PythonEnvironment {
|
|||
PythonEnvironment::new(path, origin, system)
|
||||
}
|
||||
|
||||
if let Ok(virtual_env) = system.env_var("VIRTUAL_ENV") {
|
||||
if let Ok(virtual_env) = system.env_var(EnvVars::VIRTUAL_ENV) {
|
||||
return resolve_environment(
|
||||
system,
|
||||
SystemPath::new(&virtual_env),
|
||||
|
@ -158,7 +159,7 @@ impl PythonEnvironment {
|
|||
.map(Some);
|
||||
}
|
||||
|
||||
if let Ok(conda_env) = system.env_var("CONDA_PREFIX") {
|
||||
if let Ok(conda_env) = system.env_var(EnvVars::CONDA_PREFIX) {
|
||||
return resolve_environment(
|
||||
system,
|
||||
SystemPath::new(&conda_env),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use camino::Utf8Path;
|
||||
use dir_test::{Fixture, dir_test};
|
||||
use ty_static::EnvVars;
|
||||
use ty_test::OutputFormat;
|
||||
|
||||
/// See `crates/ty_test/README.md` for documentation on these tests.
|
||||
|
@ -19,7 +20,7 @@ fn mdtest(fixture: Fixture<&str>) {
|
|||
|
||||
let test_name = test_name("mdtest", absolute_fixture_path);
|
||||
|
||||
let output_format = if std::env::var("MDTEST_GITHUB_ANNOTATIONS_FORMAT").is_ok() {
|
||||
let output_format = if std::env::var(EnvVars::MDTEST_GITHUB_ANNOTATIONS_FORMAT).is_ok() {
|
||||
OutputFormat::GitHub
|
||||
} else {
|
||||
OutputFormat::Cli
|
||||
|
|
19
crates/ty_static/Cargo.toml
Normal file
19
crates/ty_static/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "ty_static"
|
||||
version = "0.0.1"
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
documentation = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ty_macros = { workspace = true }
|
71
crates/ty_static/src/env_vars.rs
Normal file
71
crates/ty_static/src/env_vars.rs
Normal file
|
@ -0,0 +1,71 @@
|
|||
use ty_macros::attribute_env_vars_metadata;
|
||||
|
||||
/// Declares all environment variable used throughout `ty` and its crates.
|
||||
pub struct EnvVars;
|
||||
|
||||
#[attribute_env_vars_metadata]
|
||||
impl EnvVars {
|
||||
/// If set, ty will use this value as the log level for its `--verbose` output.
|
||||
/// Accepts any filter compatible with the `tracing_subscriber` crate.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// - `TY_LOG=uv=debug` is the equivalent of `-vv` to the command line
|
||||
/// - `TY_LOG=trace` will enable all trace-level logging.
|
||||
///
|
||||
/// See the [tracing documentation](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#example-syntax)
|
||||
/// for more.
|
||||
pub const TY_LOG: &'static str = "TY_LOG";
|
||||
|
||||
/// If set to `"1"` or `"true"`, ty will enable flamegraph profiling.
|
||||
/// This creates a `tracing.folded` file that can be used to generate flame graphs
|
||||
/// for performance analysis.
|
||||
pub const TY_LOG_PROFILE: &'static str = "TY_LOG_PROFILE";
|
||||
|
||||
/// Control memory usage reporting format after ty execution.
|
||||
///
|
||||
/// Accepted values:
|
||||
///
|
||||
/// * `short` - Display short memory report
|
||||
/// * `mypy_primer` - Display mypy_primer format and suppress workspace diagnostics
|
||||
/// * `full` - Display full memory report
|
||||
#[attr_hidden]
|
||||
pub const TY_MEMORY_REPORT: &'static str = "TY_MEMORY_REPORT";
|
||||
|
||||
/// Specifies an upper limit for the number of tasks ty is allowed to run in parallel.
|
||||
///
|
||||
/// For example, how many files should be checked in parallel.
|
||||
/// This isn't the same as a thread limit. ty may spawn additional threads
|
||||
/// when necessary, e.g. to watch for file system changes or a dedicated UI thread.
|
||||
pub const TY_MAX_PARALLELISM: &'static str = "TY_MAX_PARALLELISM";
|
||||
|
||||
/// Used to detect an activated virtual environment.
|
||||
pub const VIRTUAL_ENV: &'static str = "VIRTUAL_ENV";
|
||||
|
||||
/// Used to detect an activated Conda environment location.
|
||||
/// If both `VIRTUAL_ENV` and `CONDA_PREFIX` are present, `VIRTUAL_ENV` will be preferred.
|
||||
pub const CONDA_PREFIX: &'static str = "CONDA_PREFIX";
|
||||
|
||||
/// Filter which tests to run in mdtest.
|
||||
///
|
||||
/// Only tests whose names contain this filter string will be executed.
|
||||
#[attr_hidden]
|
||||
pub const MDTEST_TEST_FILTER: &'static str = "MDTEST_TEST_FILTER";
|
||||
|
||||
/// Switch mdtest output format to GitHub Actions annotations.
|
||||
///
|
||||
/// If set (to any value), mdtest will output errors in GitHub Actions format.
|
||||
#[attr_hidden]
|
||||
pub const MDTEST_GITHUB_ANNOTATIONS_FORMAT: &'static str = "MDTEST_GITHUB_ANNOTATIONS_FORMAT";
|
||||
|
||||
// Externally defined environment variables
|
||||
|
||||
/// Specifies an upper limit for the number of threads ty uses when performing work in parallel.
|
||||
/// Equivalent to `TY_MAX_PARALLELISM`.
|
||||
///
|
||||
/// This is a standard Rayon environment variable.
|
||||
pub const RAYON_NUM_THREADS: &'static str = "RAYON_NUM_THREADS";
|
||||
|
||||
/// Path to user-level configuration directory on Unix systems.
|
||||
pub const XDG_CONFIG_HOME: &'static str = "XDG_CONFIG_HOME";
|
||||
}
|
3
crates/ty_static/src/lib.rs
Normal file
3
crates/ty_static/src/lib.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
pub use env_vars::*;
|
||||
|
||||
mod env_vars;
|
|
@ -19,6 +19,7 @@ ruff_source_file = { workspace = true }
|
|||
ruff_text_size = { workspace = true }
|
||||
ruff_python_ast = { workspace = true }
|
||||
ty_python_semantic = { workspace = true, features = ["serde", "testing"] }
|
||||
ty_static = { workspace = true }
|
||||
ty_vendored = { workspace = true }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
|
|
|
@ -29,7 +29,7 @@ mod diagnostic;
|
|||
mod matcher;
|
||||
mod parser;
|
||||
|
||||
const MDTEST_TEST_FILTER: &str = "MDTEST_TEST_FILTER";
|
||||
use ty_static::EnvVars;
|
||||
|
||||
/// Run `path` as a markdown test suite with given `title`.
|
||||
///
|
||||
|
@ -53,7 +53,7 @@ pub fn run(
|
|||
|
||||
let mut db = db::Db::setup();
|
||||
|
||||
let filter = std::env::var(MDTEST_TEST_FILTER).ok();
|
||||
let filter = std::env::var(EnvVars::MDTEST_TEST_FILTER).ok();
|
||||
let mut any_failures = false;
|
||||
for test in suite.tests() {
|
||||
if filter
|
||||
|
@ -105,10 +105,12 @@ pub fn run(
|
|||
|
||||
if output_format.is_cli() {
|
||||
println!(
|
||||
"\nTo rerun this specific test, set the environment variable: {MDTEST_TEST_FILTER}='{escaped_test_name}'",
|
||||
"\nTo rerun this specific test, set the environment variable: {}='{escaped_test_name}'",
|
||||
EnvVars::MDTEST_TEST_FILTER,
|
||||
);
|
||||
println!(
|
||||
"{MDTEST_TEST_FILTER}='{escaped_test_name}' cargo test -p ty_python_semantic --test mdtest -- {test_name}",
|
||||
"{}='{escaped_test_name}' cargo test -p ty_python_semantic --test mdtest -- {test_name}",
|
||||
EnvVars::MDTEST_TEST_FILTER,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue