use super::{
npm::{NpmProvider, PackageJson, DEFAULT_NODE_PKG_NAME},
Provider,
};
use crate::nixpacks::{
app::App,
environment::{Environment, EnvironmentVariables},
nix::Pkg,
phase::{BuildPhase, InstallPhase, SetupPhase, StartPhase},
};
use anyhow::Result;
pub struct YarnProvider {}
impl Provider for YarnProvider {
fn name(&self) -> &str {
"yarn"
}
fn detect(&self, app: &App, _env: &Environment) -> Result<bool> {
Ok(app.includes_file("package.json") && app.includes_file("yarn.lock"))
}
fn setup(&self, app: &App, _env: &Environment) -> Result<Option<SetupPhase>> {
let package_json: PackageJson = app.read_json("package.json")?;
let node_pkg = NpmProvider::get_nix_node_pkg(&package_json)?;
let mut yarn_pkg = Pkg::new("yarn");
if node_pkg.name != *DEFAULT_NODE_PKG_NAME {
yarn_pkg = yarn_pkg.set_override("nodejs", node_pkg.name.as_str());
}
Ok(Some(SetupPhase::new(vec![yarn_pkg])))
}
fn install(&self, app: &App, _env: &Environment) -> Result<Option<InstallPhase>> {
let package_json: PackageJson = app.read_json("package.json")?;
let mut install_phase = InstallPhase::new("yarn install --frozen-lockfile".to_string());
if package_json.workspaces.is_none() {
install_phase.add_file_dependency("package.json".to_string());
install_phase.add_file_dependency("yarn.lock".to_string());
}
Ok(Some(install_phase))
}
fn build(&self, app: &App, _env: &Environment) -> Result<Option<BuildPhase>> {
if NpmProvider::has_script(app, "build")? {
Ok(Some(BuildPhase::new("yarn build".to_string())))
} else {
Ok(None)
}
}
fn start(&self, app: &App, _env: &Environment) -> Result<Option<StartPhase>> {
if let Some(start_cmd) = NpmProvider::get_start_cmd(app)? {
Ok(Some(StartPhase::new(start_cmd.replace("npm run", "yarn"))))
} else {
Ok(None)
}
}
fn environment_variables(
&self,
_app: &App,
_env: &Environment,
) -> Result<Option<EnvironmentVariables>> {
Ok(Some(NpmProvider::get_node_environment_variables()))
}
}