cargo_gazelle/
header.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! Helpers to generate the header of a Bazel file.
11
12use crate::rules::LoadStatement;
13use crate::targets::RustTarget;
14
15use super::ToBazelDefinition;
16use std::collections::BTreeMap;
17
18use std::fmt;
19
20static CODE_GENERATED_HEADER: &str = "# Code generated by cargo-gazelle DO NOT EDIT
21
22# Copyright Materialize, Inc. and contributors. All rights reserved.
23#
24# Use of this software is governed by the Business Source License
25# included in the LICENSE file at the root of this repository.
26#
27# As of the Change Date specified in that file, in accordance with
28# the Business Source License, use of this software will be governed
29# by the Apache License, Version 2.0.
30";
31
32/// Header to include on a BUILD.bazel file.
33///
34/// Includes special text to indicate this file is generated, and imports any necessary Rust rules.
35///
36/// TODO(parkmycar): This works for now but should surely be refactored.
37#[derive(Debug)]
38pub struct BazelHeader {
39    loads: Vec<LoadStatement>,
40}
41
42impl BazelHeader {
43    pub fn generate(targets: &[Box<dyn RustTarget>]) -> Self {
44        let x = targets
45            .iter()
46            .flat_map(|t| t.rules().into_iter())
47            .map(|rule| (rule.module(), rule));
48
49        let mut rules = BTreeMap::new();
50        for (module, rule) in x {
51            let entry = rules.entry(module).or_insert(Vec::new());
52            entry.push(rule);
53        }
54
55        let loads = rules.into_iter().map(LoadStatement::from).collect();
56
57        BazelHeader { loads }
58    }
59}
60
61impl ToBazelDefinition for BazelHeader {
62    fn format(&self, writer: &mut dyn fmt::Write) -> Result<(), fmt::Error> {
63        writeln!(writer, "{CODE_GENERATED_HEADER}")?;
64        writeln!(writer)?;
65        writeln!(
66            writer,
67            r#"package(default_visibility = ["//visibility:public"])"#
68        )?;
69        writeln!(writer)?;
70
71        // TODO(parkmcar): Handle differently named root repositories.
72        writeln!(
73            writer,
74            r#"load("@crates_io//:defs.bzl", "aliases", "all_crate_deps")"#
75        )?;
76
77        for stmt in &self.loads {
78            stmt.format(writer)?;
79            writeln!(writer)?;
80        }
81
82        Ok(())
83    }
84}