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

[mysten-service] 6/n update the sui-services dockerfile with new service #15873

Merged
merged 2 commits into from
Jan 25, 2024
Merged
Changes from all 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
93 changes: 90 additions & 3 deletions crates/suiop-cli/src/cli/service/init.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use anyhow::Context;
use anyhow::Result;
use clap::Parser;
use clap::ValueEnum;
use include_dir::{include_dir, Dir};
use std::fs;
use std::fs::create_dir_all;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use tracing::debug;
use tracing::info;

// include the boilerplate code in this binary
Expand All @@ -27,12 +30,83 @@ pub fn bootstrap_service(lang: &ServiceLanguage, path: &Path) -> Result<()> {
}
}

/// Add the new service to the sui-services dockerfile in the sui repository
fn add_to_sui_dockerfile(path: &Path) -> Result<()> {
let path = path.canonicalize().context("canonicalizing service path")?;
let crates_dir = path.parent().unwrap();
if !crates_dir.ends_with("sui/crates") {
panic!("directory wasn't in the sui repo");
}
let sui_services_dockerfile_path = &crates_dir.join("../docker/sui-services/Dockerfile");
// read the dockerfile
let dockerfile = fs::read_to_string(sui_services_dockerfile_path)
.context("reading sui-services dockerfile")?;

// find the line with the build cmd
let build_line = dockerfile
.lines()
.enumerate()
.find(|(_, line)| line.contains("RUN cargo build --release \\"))
.expect("couldn't find build line in sui-services dockerfile")
.0;
// update with the new service
let mut final_dockerfile = dockerfile.lines().collect::<Vec<_>>();
let bin_str = format!(
" --bin {} \\",
path.file_name()
.expect("getting the project name from the given path")
.to_str()
.unwrap()
);
final_dockerfile.insert(build_line + 1, &bin_str);
// write the file back
fs::write(sui_services_dockerfile_path, final_dockerfile.join("\n"))
.context("writing sui-services dockerfile after modifying it")?;

Ok(())
}

fn add_member_to_workspace(path: &Path) -> Result<()> {
// test
let path = path.canonicalize().context("canonicalizing service path")?;
let crates_dir = path.parent().unwrap();
if !crates_dir.ends_with("sui/crates") {
panic!("directory wasn't in the sui repo");
}
let workspace_toml_path = &crates_dir.join("../Cargo.toml");
// read the workspace toml
let toml_content = fs::read_to_string(workspace_toml_path)?;
let mut toml = toml_content.parse::<toml_edit::Document>()?;
toml["workspace"]["members"]
.as_array_mut()
.unwrap()
.push_formatted(toml_edit::Value::String(toml_edit::Formatted::new(
path.file_name()
.expect("getting the project name from the given path")
.to_str()
.unwrap()
.to_string(),
)));
fs::write(workspace_toml_path, toml.to_string())
.context("failed to write workspace Cargo.toml back after update")?;
Ok(())
}

fn create_rust_service(path: &Path) -> Result<()> {
info!("creating rust service in {}", path.to_string_lossy());
let cargo_toml_path = if path.to_string_lossy().contains("sui/crates") {
"Cargo-sui.toml"
} else {
// create the dir to ensure we can canonicalize any relative paths
create_dir_all(path)?;
let is_sui_service = path
// expand relative paths and symlinks
.canonicalize()
.context("canonicalizing service path")?
.to_string_lossy()
.contains("sui/crates");
debug!("sui service: {:?}", is_sui_service);
let cargo_toml_path = if is_sui_service {
"Cargo.toml"
} else {
"Cargo-external.toml"
};
let cargo_toml = PROJECT_DIR.get_file(cargo_toml_path).unwrap();
let main_rs = PROJECT_DIR.get_file("src/main.rs").unwrap();
Expand All @@ -43,5 +117,18 @@ fn create_rust_service(path: &Path) -> Result<()> {
main_file.write_all(main_body)?;
let mut cargo_file = File::create(path.join("Cargo.toml"))?;
cargo_file.write_all(cargo_body)?;

// add the project as a member of the cargo workspace
if is_sui_service {
add_member_to_workspace(path)?;
}
// now that the source directory works, let's update/add a dockerfile
if is_sui_service {
// update sui-services dockerfile
add_to_sui_dockerfile(path)?;
} else {
// TODO: create a new dockerfile where the user designates
}

Ok(())
}
Loading