Makefile

Struct Makefile 

Source
pub struct Makefile(/* private fields */);
Expand description

An AST node for $ast

Implementations§

Source§

impl Makefile

Source

pub fn new() -> Makefile

Create a new empty makefile

Source

pub fn parse(text: &str) -> Parse<Makefile>

Parse makefile text, returning a Parse result

Source

pub fn code(&self) -> String

Get the text content of the makefile

Source

pub fn is_root(&self) -> bool

Check if this node is the root of a makefile

Source

pub fn read<R: Read>(r: R) -> Result<Makefile, Error>

Read a makefile from a reader

Source

pub fn read_relaxed<R: Read>(r: R) -> Result<Makefile, Error>

Read makefile from a reader, but allow syntax errors

Source

pub fn rules(&self) -> impl Iterator<Item = Rule> + '_

Retrieve the rules in the makefile

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "rule: dependency\n\tcommand\n".parse().unwrap();
assert_eq!(makefile.rules().count(), 1);
Source

pub fn rules_by_target<'a>( &'a self, target: &'a str, ) -> impl Iterator<Item = Rule> + 'a

Get all rules that have a specific target

Source

pub fn variable_definitions(&self) -> impl Iterator<Item = VariableDefinition>

Get all variable definitions in the makefile

Source

pub fn conditionals(&self) -> impl Iterator<Item = Conditional> + '_

Get all conditionals in the makefile

Source

pub fn items(&self) -> impl Iterator<Item = MakefileItem> + '_

Get all top-level items (rules, variables, includes, conditionals) in the makefile

§Example
use makefile_lossless::{Makefile, MakefileItem};
let makefile: Makefile = r#"VAR = value
ifdef DEBUG
CFLAGS = -g
endif
rule:
	command
"#.parse().unwrap();
let items: Vec<_> = makefile.items().collect();
assert_eq!(items.len(), 3); // VAR, conditional, rule
Source

pub fn find_variable<'a>( &'a self, name: &'a str, ) -> impl Iterator<Item = VariableDefinition> + 'a

Find all variables by name

Returns an iterator over all variable definitions with the given name. Makefiles can have multiple definitions of the same variable.

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "VAR1 = value1\nVAR2 = value2\nVAR1 = value3\n".parse().unwrap();
let vars: Vec<_> = makefile.find_variable("VAR1").collect();
assert_eq!(vars.len(), 2);
assert_eq!(vars[0].raw_value(), Some("value1".to_string()));
assert_eq!(vars[1].raw_value(), Some("value3".to_string()));
Source

pub fn add_rule(&mut self, target: &str) -> Rule

Add a new rule to the makefile

§Example
use makefile_lossless::Makefile;
let mut makefile = Makefile::new();
makefile.add_rule("rule");
assert_eq!(makefile.to_string(), "rule:\n");
Source

pub fn add_conditional( &mut self, conditional_type: &str, condition: &str, if_body: &str, else_body: Option<&str>, ) -> Result<Conditional, Error>

Add a new conditional to the makefile

§Arguments
  • conditional_type - The type of conditional: “ifdef”, “ifndef”, “ifeq”, or “ifneq”
  • condition - The condition expression (e.g., “DEBUG” for ifdef/ifndef, or “(a,b)” for ifeq/ifneq)
  • if_body - The content of the if branch
  • else_body - Optional content for the else branch
§Example
use makefile_lossless::Makefile;
let mut makefile = Makefile::new();
makefile.add_conditional("ifdef", "DEBUG", "VAR = debug\n", None);
assert!(makefile.to_string().contains("ifdef DEBUG"));
Source

pub fn add_conditional_with_items<I1, I2>( &mut self, conditional_type: &str, condition: &str, if_items: I1, else_items: Option<I2>, ) -> Result<Conditional, Error>
where I1: IntoIterator<Item = MakefileItem>, I2: IntoIterator<Item = MakefileItem>,

Add a new conditional to the makefile with typed items

This is a more type-safe alternative to add_conditional that accepts iterators of MakefileItem instead of raw strings.

§Arguments
  • conditional_type - The type of conditional: “ifdef”, “ifndef”, “ifeq”, or “ifneq”
  • condition - The condition expression (e.g., “DEBUG” for ifdef/ifndef, or “(a,b)” for ifeq/ifneq)
  • if_items - Items for the if branch
  • else_items - Optional items for the else branch
§Example
use makefile_lossless::{Makefile, MakefileItem};
let mut makefile = Makefile::new();
let temp1: Makefile = "CFLAGS = -g\n".parse().unwrap();
let var1 = temp1.variable_definitions().next().unwrap();
let temp2: Makefile = "CFLAGS = -O2\n".parse().unwrap();
let var2 = temp2.variable_definitions().next().unwrap();
makefile.add_conditional_with_items(
    "ifdef",
    "DEBUG",
    vec![MakefileItem::Variable(var1)],
    Some(vec![MakefileItem::Variable(var2)])
).unwrap();
assert!(makefile.to_string().contains("ifdef DEBUG"));
assert!(makefile.to_string().contains("CFLAGS = -g"));
assert!(makefile.to_string().contains("CFLAGS = -O2"));
Source

pub fn from_reader<R: Read>(r: R) -> Result<Makefile, Error>

Read the makefile

Source

pub fn replace_rule( &mut self, index: usize, new_rule: Rule, ) -> Result<(), Error>

Replace rule at given index with a new rule

§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let new_rule: makefile_lossless::Rule = "new_rule:\n\tnew_command\n".parse().unwrap();
makefile.replace_rule(0, new_rule).unwrap();
assert!(makefile.rules().any(|r| r.targets().any(|t| t == "new_rule")));
Source

pub fn remove_rule(&mut self, index: usize) -> Result<Rule, Error>

Remove rule at given index

§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let removed = makefile.remove_rule(0).unwrap();
assert_eq!(removed.targets().collect::<Vec<_>>(), vec!["rule1"]);
assert_eq!(makefile.rules().count(), 1);
Source

pub fn insert_rule(&mut self, index: usize, new_rule: Rule) -> Result<(), Error>

Insert rule at given position

§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let new_rule: makefile_lossless::Rule = "inserted_rule:\n\tinserted_command\n".parse().unwrap();
makefile.insert_rule(1, new_rule).unwrap();
let targets: Vec<_> = makefile.rules().flat_map(|r| r.targets().collect::<Vec<_>>()).collect();
assert_eq!(targets, vec!["rule1", "inserted_rule", "rule2"]);
Source

pub fn includes(&self) -> impl Iterator<Item = Include>

Get all include directives in the makefile

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "include config.mk\n-include .env\n".parse().unwrap();
let includes = makefile.includes().collect::<Vec<_>>();
assert_eq!(includes.len(), 2);
Source

pub fn included_files(&self) -> impl Iterator<Item = String> + '_

Get all included file paths

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "include config.mk\n-include .env\n".parse().unwrap();
let paths = makefile.included_files().collect::<Vec<_>>();
assert_eq!(paths, vec!["config.mk", ".env"]);
Source

pub fn find_rule_by_target(&self, target: &str) -> Option<Rule>

Find the first rule with a specific target name

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "rule1:\n\tcommand1\nrule2:\n\tcommand2\n".parse().unwrap();
let rule = makefile.find_rule_by_target("rule2");
assert!(rule.is_some());
assert_eq!(rule.unwrap().targets().collect::<Vec<_>>(), vec!["rule2"]);
Source

pub fn find_rules_by_target<'a>( &'a self, target: &'a str, ) -> impl Iterator<Item = Rule> + 'a

Find all rules with a specific target name

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "rule1:\n\tcommand1\nrule1:\n\tcommand2\nrule2:\n\tcommand3\n".parse().unwrap();
let rules: Vec<_> = makefile.find_rules_by_target("rule1").collect();
assert_eq!(rules.len(), 2);
Source

pub fn find_rule_by_target_pattern(&self, target: &str) -> Option<Rule>

Find the first rule whose target matches the given pattern

Supports make-style pattern matching where % in a rule’s target acts as a wildcard. For example, a rule with target %.o will match foo.o, bar.o, etc.

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "%.o: %.c\n\t$(CC) -c $<\n".parse().unwrap();
let rule = makefile.find_rule_by_target_pattern("foo.o");
assert!(rule.is_some());
Source

pub fn find_rules_by_target_pattern<'a>( &'a self, target: &'a str, ) -> impl Iterator<Item = Rule> + 'a

Find all rules whose targets match the given pattern

Supports make-style pattern matching where % in a rule’s target acts as a wildcard. For example, a rule with target %.o will match foo.o, bar.o, etc.

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = "%.o: %.c\n\t$(CC) -c $<\n%.o: %.s\n\t$(AS) -o $@ $<\n".parse().unwrap();
let rules: Vec<_> = makefile.find_rules_by_target_pattern("foo.o").collect();
assert_eq!(rules.len(), 2);
Source

pub fn add_phony_target(&mut self, target: &str) -> Result<(), Error>

Add a target to .PHONY (creates .PHONY rule if it doesn’t exist)

§Example
use makefile_lossless::Makefile;
let mut makefile = Makefile::new();
makefile.add_phony_target("clean").unwrap();
assert!(makefile.is_phony("clean"));
Source

pub fn remove_phony_target(&mut self, target: &str) -> Result<bool, Error>

Remove a target from .PHONY (removes .PHONY rule if it becomes empty)

Returns true if the target was found and removed, false if it wasn’t in .PHONY. If there are multiple .PHONY rules, it removes the target from the first rule that contains it.

§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = ".PHONY: clean test\n".parse().unwrap();
assert!(makefile.remove_phony_target("clean").unwrap());
assert!(!makefile.is_phony("clean"));
assert!(makefile.is_phony("test"));
Source

pub fn is_phony(&self, target: &str) -> bool

Check if a target is marked as phony

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = ".PHONY: clean test\n".parse().unwrap();
assert!(makefile.is_phony("clean"));
assert!(makefile.is_phony("test"));
assert!(!makefile.is_phony("build"));
Source

pub fn phony_targets(&self) -> impl Iterator<Item = String> + '_

Get all phony targets

§Example
use makefile_lossless::Makefile;
let makefile: Makefile = ".PHONY: clean test build\n".parse().unwrap();
let phony_targets: Vec<_> = makefile.phony_targets().collect();
assert_eq!(phony_targets, vec!["clean", "test", "build"]);
Source

pub fn add_include(&mut self, path: &str) -> Include

Add a new include directive at the beginning of the makefile

§Arguments
  • path - The file path to include (e.g., “config.mk”)
§Example
use makefile_lossless::Makefile;
let mut makefile = Makefile::new();
makefile.add_include("config.mk");
assert_eq!(makefile.included_files().collect::<Vec<_>>(), vec!["config.mk"]);
Source

pub fn insert_include( &mut self, index: usize, path: &str, ) -> Result<Include, Error>

Insert an include directive at a specific position

The position is relative to other top-level items (rules, variables, includes, conditionals).

§Arguments
  • index - The position to insert at (0 = beginning, items().count() = end)
  • path - The file path to include (e.g., “config.mk”)
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "VAR = value\nrule:\n\tcommand\n".parse().unwrap();
makefile.insert_include(1, "config.mk").unwrap();
let items: Vec<_> = makefile.items().collect();
assert_eq!(items.len(), 3); // VAR, include, rule
Source

pub fn insert_include_after( &mut self, after: &MakefileItem, path: &str, ) -> Result<Include, Error>

Insert an include directive after a specific MakefileItem

This is useful when you want to insert an include relative to another item in the makefile.

§Arguments
  • after - The MakefileItem to insert after
  • path - The file path to include (e.g., “config.mk”)
§Example
use makefile_lossless::Makefile;
let mut makefile: Makefile = "VAR1 = value1\nVAR2 = value2\n".parse().unwrap();
let first_var = makefile.items().next().unwrap();
makefile.insert_include_after(&first_var, "config.mk").unwrap();
let paths: Vec<_> = makefile.included_files().collect();
assert_eq!(paths, vec!["config.mk"]);
Source§

impl Makefile

Source

pub fn line(&self) -> usize

Get the line number (0-indexed) where this node starts.

Source

pub fn column(&self) -> usize

Get the column number (0-indexed, in bytes) where this node starts.

Source

pub fn line_col(&self) -> (usize, usize)

Get both line and column (0-indexed) where this node starts. Returns (line, column) where column is measured in bytes from the start of the line.

Trait Implementations§

Source§

impl AstNode for Makefile

Source§

type Language = Lang

Source§

fn can_cast(kind: SyntaxKind) -> bool

Source§

fn cast(syntax: SyntaxNode<Lang>) -> Option<Self>

Source§

fn syntax(&self) -> &SyntaxNode<Lang>

Source§

fn clone_for_update(&self) -> Self
where Self: Sized,

Source§

fn clone_subtree(&self) -> Self
where Self: Sized,

Source§

impl Clone for Makefile

Source§

fn clone(&self) -> Makefile

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Default for Makefile

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Display for Makefile

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl FromStr for Makefile

Source§

type Err = Error

The associated error which can be returned from parsing.
Source§

fn from_str(s: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
Source§

impl Hash for Makefile

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Makefile

Source§

fn eq(&self, other: &Makefile) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Eq for Makefile

Source§

impl StructuralPartialEq for Makefile

Auto Trait Implementations§

Blanket Implementations§

§

impl<T> Any for T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T> ToString for T
where T: Display + ?Sized,

§

fn to_string(&self) -> String

Converts the given value to a String. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.