scarb 0.5.2

The Cairo package manager
Documentation
use std::io::Write;

use anyhow::{Context, Result};
use cairo_lang_compiler::db::RootDatabase;
use cairo_lang_sierra_to_casm::metadata::{calc_metadata, MetadataComputationConfig};
use serde::{Deserialize, Serialize};
use tracing::trace_span;

use crate::compiler::helpers::{build_compiler_config, collect_main_crate_ids};
use crate::compiler::{CompilationUnit, Compiler};
use crate::core::{Target, Workspace};

pub struct LibCompiler;

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
struct Props {
    pub sierra: bool,
    pub casm: bool,
}

impl Default for Props {
    fn default() -> Self {
        Self {
            sierra: true,
            casm: false,
        }
    }
}

impl Compiler for LibCompiler {
    fn target_kind(&self) -> &str {
        Target::LIB
    }

    fn compile(
        &self,
        unit: CompilationUnit,
        db: &mut RootDatabase,
        ws: &Workspace<'_>,
    ) -> Result<()> {
        let props: Props = unit.target().props()?;
        if !props.sierra && !props.casm {
            ws.config().ui().warn(
                "both Sierra and CASM lib targets have been disabled, \
                Scarb will not produce anything",
            );
        }

        let target_dir = unit.target_dir(ws.config());

        let compiler_config = build_compiler_config(&unit, ws);

        let main_crate_ids = collect_main_crate_ids(&unit, db);

        let sierra_program = {
            let _ = trace_span!("compile_sierra").enter();
            cairo_lang_compiler::compile_prepared_db(db, main_crate_ids, compiler_config)?
        };

        if props.sierra {
            let mut file = target_dir.open_rw(
                format!("{}.sierra", unit.target().name),
                "output file",
                ws.config(),
            )?;
            file.write_all(sierra_program.to_string().as_bytes())?;
        }

        if props.casm {
            let gas_usage_check = true;

            let metadata = {
                let _ = trace_span!("casm_calc_metadata");
                calc_metadata(&sierra_program, MetadataComputationConfig::default())
                    .context("failed calculating Sierra variables")?
            };

            let cairo_program = {
                let _ = trace_span!("compile_casm");
                cairo_lang_sierra_to_casm::compiler::compile(
                    &sierra_program,
                    &metadata,
                    gas_usage_check,
                )?
            };

            let mut file = target_dir.open_rw(
                format!("{}.casm", unit.target().name),
                "output file",
                ws.config(),
            )?;
            file.write_all(cairo_program.to_string().as_bytes())?;
        }

        Ok(())
    }
}