Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add buffrs new command to init a package in a non-existing folder #256

Merged
merged 5 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 42 additions & 4 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ use crate::{
use async_recursion::async_recursion;
use miette::{bail, ensure, miette, Context as _, IntoDiagnostic};
use semver::{Version, VersionReq};
use std::{env, path::Path, str::FromStr};
use std::{
env,
path::{Path, PathBuf},
str::FromStr,
};
use tokio::{
fs,
io::{self, AsyncBufReadExt, BufReader},
Expand Down Expand Up @@ -68,7 +72,7 @@ pub async fn init(kind: Option<PackageType>, name: Option<PackageName>) -> miett

let manifest = Manifest::new(package, vec![]);

manifest.write().await?;
manifest.write(None).await?;

PackageStore::open(std::env::current_dir().unwrap_or_else(|_| ".".into()))
.await
Expand All @@ -77,6 +81,40 @@ pub async fn init(kind: Option<PackageType>, name: Option<PackageName>) -> miett
Ok(())
}

/// Initializes a project with the given name in the current directory
pub async fn new(kind: Option<PackageType>, name: PackageName) -> miette::Result<()> {
let mut package_dir: PathBuf = ".".into();
package_dir.push::<String>(name.clone().into());
gbouv marked this conversation as resolved.
Show resolved Hide resolved
// create_dir fails if the folder already exists
fs::create_dir(&package_dir)
.await
.into_diagnostic()
.wrap_err(miette!(
"failed to create {} directory",
package_dir.display()
))?;

let package = kind
.map(|kind| -> miette::Result<PackageManifest> {
Ok(PackageManifest {
kind,
name,
version: INITIAL_VERSION,
description: None,
})
})
.transpose()?;

let manifest = Manifest::new(package, vec![]);
manifest.write(Some(package_dir.clone())).await?;

PackageStore::open(&package_dir)
.await
.wrap_err(miette!("failed to create buffrs `proto` directories"))?;

Ok(())
}

struct DependencyLocator {
repository: String,
package: PackageName,
Expand Down Expand Up @@ -139,7 +177,7 @@ pub async fn add(registry: RegistryUri, dependency: &str) -> miette::Result<()>
.push(Dependency::new(registry, repository, package, version));

manifest
.write()
.write(None)
gbouv marked this conversation as resolved.
Show resolved Hide resolved
.await
.wrap_err(miette!("failed to write `{MANIFEST_FILE}`"))
}
Expand All @@ -159,7 +197,7 @@ pub async fn remove(package: PackageName) -> miette::Result<()> {

store.uninstall(&dependency.package).await.ok();

manifest.write().await
manifest.write(None).await
}

/// Packages the api and writes it to the filesystem
Expand Down
40 changes: 33 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ enum Command {
package: Option<PackageName>,
},

/// Creates a new buffrs package in the current directory
New {
/// Sets up the package as lib
#[clap(long, conflicts_with = "api")]
#[arg(group = "pkg")]
lib: bool,
/// Sets up the package as api
#[clap(long, conflicts_with = "lib")]
#[arg(group = "pkg")]
api: bool,
/// The package name
#[clap(requires = "pkg")]
package: PackageName,
},

/// Check rule violations for this package.
Lint,

Expand Down Expand Up @@ -177,13 +192,7 @@ async fn main() -> miette::Result<()> {

match cli.command {
Command::Init { lib, api, package } => {
let kind = if lib {
Some(PackageType::Lib)
} else if api {
Some(PackageType::Api)
} else {
None
};
let kind = infer_package_type(lib, api);

command::init(kind, package.to_owned())
.await
Expand All @@ -192,6 +201,13 @@ async fn main() -> miette::Result<()> {
package.map(|p| format!("`{p}`")).unwrap_or_default()
))
}
Command::New { lib, api, package } => {
let kind = infer_package_type(lib, api);

command::new(kind, package.to_owned())
.await
.wrap_err(miette!("failed to initialize {}", format!("`{package}`")))
}
Command::Login { registry } => command::login(registry.to_owned())
.await
.wrap_err(miette!("failed to login to `{registry}`")),
Expand Down Expand Up @@ -255,3 +271,13 @@ async fn main() -> miette::Result<()> {
},
}
}

fn infer_package_type(lib: bool, api: bool) -> Option<PackageType> {
if lib {
Some(PackageType::Lib)
} else if api {
Some(PackageType::Api)
} else {
None
}
}
10 changes: 6 additions & 4 deletions src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fmt::{self, Display},
path::Path,
path::{Path, PathBuf},
str::FromStr,
};
use tokio::fs;
Expand Down Expand Up @@ -313,16 +313,18 @@ impl Manifest {
Ok(Some(raw.into()))
}

/// Persists the manifest into the current directory
pub async fn write(&self) -> miette::Result<()> {
/// Persists the manifest into the provided directory, which must exist (or current directory if None)
pub async fn write(&self, dir_path: Option<PathBuf>) -> miette::Result<()> {
// hint: create a canary manifest from the current one
let raw = RawManifest::from(Manifest::new(
self.package.clone(),
self.dependencies.clone(),
));

let mut manifest_file_path = dir_path.unwrap_or_else(|| ".".into());
manifest_file_path.push(MANIFEST_FILE);
fs::write(
MANIFEST_FILE,
manifest_file_path,
toml::to_string(&raw)
.into_diagnostic()
.wrap_err(SerializationError(ManagedFile::Manifest))?
Expand Down
Loading