add fetch source code
This commit is contained in:
@@ -12,9 +12,10 @@ use std::env;
|
||||
|
||||
use nixideserver_lib::*;
|
||||
fn main() {
|
||||
let eng = DummyEngine {};
|
||||
let _eng = DummyEngine {};
|
||||
let _podman_eng = PodmanEngine::new(env::current_dir().unwrap());
|
||||
let exectuor = NixIdeManageService::new(Box::new(eng));
|
||||
//let exectuor = NixIdeManageService::new(Box::new(eng));
|
||||
let exectuor = NixIdeManageService::new(Box::new(_podman_eng));
|
||||
rocket::ignite()
|
||||
.mount(
|
||||
"/api/v1/",
|
||||
|
||||
@@ -38,9 +38,9 @@ pub enum IdeState {
|
||||
|
||||
#[derive(Serialize, Deserialize, Hash, JsonSchema)]
|
||||
pub struct OpenGitParam {
|
||||
inquirer: String,
|
||||
clone_url: String,
|
||||
ref_name: String,
|
||||
pub inquirer: String,
|
||||
pub clone_url: String,
|
||||
pub ref_name: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Hash, JsonSchema)]
|
||||
@@ -52,7 +52,7 @@ pub struct IdeStateResponse {
|
||||
|
||||
pub trait NixIdeManageServiceEngine {
|
||||
fn fetch_current_ide_state(&self, ide_id: &str) -> Result<IdeState, Status>;
|
||||
fn start_open(&mut self, ide_id: &str, param: &OpenGitParam) -> Result<IdeState, Status>;
|
||||
fn start_open(&self, ide_id: &str, param: &OpenGitParam) -> Result<IdeState, Status>;
|
||||
}
|
||||
|
||||
pub struct NixIdeManageService {
|
||||
@@ -74,7 +74,7 @@ impl NixIdeManageServiceEngine for DummyEngine {
|
||||
Ok(IdeState::OPENING)
|
||||
}
|
||||
|
||||
fn start_open(&mut self, _ide_id: &str, _param: &OpenGitParam) -> Result<IdeState, Status> {
|
||||
fn start_open(&self, _ide_id: &str, _param: &OpenGitParam) -> Result<IdeState, Status> {
|
||||
Ok(IdeState::OPENING)
|
||||
}
|
||||
}
|
||||
@@ -145,7 +145,7 @@ pub fn v1_open_inquirer_git(
|
||||
};
|
||||
|
||||
let ide_id = create_ide_id(¶m);
|
||||
srv.eng.borrow_mut()
|
||||
srv.eng.borrow()
|
||||
.start_open(&ide_id, ¶m)
|
||||
.map_err(|_| Error {})
|
||||
.and_then(|starting_result| {
|
||||
|
||||
@@ -9,8 +9,8 @@ extern crate serde_json;
|
||||
use nixideserver_lib::*;
|
||||
use rocket::http::Status;
|
||||
use std::fs;
|
||||
use std::io::prelude::*;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
// podman create --name test -p 3000:3000 -v $PWD:/nixide -w /nixide docker.io/nixos/nix nix-shell --pure start-ide.nix --run run_ide.sh
|
||||
|
||||
@@ -27,7 +27,9 @@ pub enum PodmanState {
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct PodmanContainer {
|
||||
ide_id: String,
|
||||
state: PodmanState,
|
||||
ide_state: IdeState,
|
||||
ide_param: NixIdeServerParam,
|
||||
}
|
||||
|
||||
@@ -42,7 +44,13 @@ pub struct PodmanEngine {
|
||||
}
|
||||
|
||||
impl PodmanEngine {
|
||||
pub fn new(working_folder: PathBuf) -> Self {
|
||||
pub fn new(working_folder: PathBuf) -> PodmanEngineTraitImpl {
|
||||
PodmanEngineTraitImpl {
|
||||
working_folder
|
||||
}
|
||||
}
|
||||
|
||||
fn _new(working_folder: PathBuf) -> Self {
|
||||
let list_path = format!("{}/.podman_containers", &working_folder.display());
|
||||
let list = match read_from_list_file(&list_path) {
|
||||
Ok(p) => p,
|
||||
@@ -58,76 +66,90 @@ impl PodmanEngine {
|
||||
}
|
||||
|
||||
pub fn save(&self) -> Result<(), std::io::Error> {
|
||||
let json_string = serde_json::to_string_pretty(&self.list).unwrap();// .map_err(|_| std::io::Error::from(std::io::ErrorKind::InvalidData))?;
|
||||
fs::write(&format!("{}/.podman_containers", &self.working_folder.display()), json_string)
|
||||
let json_string = serde_json::to_string_pretty(&self.list).unwrap(); // .map_err(|_| std::io::Error::from(std::io::ErrorKind::InvalidData))?;
|
||||
fs::write(
|
||||
&format!("{}/.podman_containers", &self.working_folder.display()),
|
||||
json_string,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn reload(trait_impl : &PodmanEngineTraitImpl) -> Result<Self, std::io::Error> {
|
||||
Ok(
|
||||
Self::_new(trait_impl.working_folder.clone())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct PodmanIdeStatus {
|
||||
ide_state: IdeState,
|
||||
}
|
||||
|
||||
impl NixIdeManageServiceEngine for PodmanEngine {
|
||||
pub struct PodmanEngineTraitImpl {
|
||||
working_folder: PathBuf
|
||||
}
|
||||
|
||||
impl NixIdeManageServiceEngine for PodmanEngineTraitImpl {
|
||||
fn fetch_current_ide_state(&self, ide_id: &str) -> Result<IdeState, Status> {
|
||||
let state_file = create_state_file_path(&self.working_folder, ide_id);
|
||||
let mut file = fs::File::open(state_file)
|
||||
.map_err(|_| Status::new(500, "could not open state file"))?;
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents)
|
||||
.map_err(|_| Status::NotFound)?;
|
||||
let ide_state =
|
||||
read_ide_state(&contents).map_err(|_| Status::new(500, "unexpected json string"))?;
|
||||
Ok(ide_state)
|
||||
let eng = PodmanEngine::reload(self)
|
||||
.map_err(|_| Status::new(500, "internal error : reload engine"))?;
|
||||
match eng.list.container.iter().find(|i| i.ide_id.eq(ide_id)) {
|
||||
Some(i) => Ok(i.ide_state.clone()),
|
||||
_ => Err(Status::NotFound),
|
||||
}
|
||||
}
|
||||
|
||||
fn start_open(&mut self, ide_id: &str, _param: &OpenGitParam) -> Result<IdeState, Status> {
|
||||
let ide_folder = create_ide_folder_path(&self.working_folder, ide_id);
|
||||
let state_file = create_state_file_path_from_ide_folder(&ide_folder);
|
||||
fs::create_dir_all(&ide_folder)
|
||||
.and_then(|_| {
|
||||
fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.read(true)
|
||||
.open(state_file)
|
||||
})
|
||||
.and_then(|mut file| {
|
||||
let mut buffer = String::new();
|
||||
match file.read_to_string(&mut buffer) {
|
||||
Ok(s) if s > 0 => read_ide_state(&buffer)
|
||||
.map_err(|_| std::io::Error::from(std::io::ErrorKind::InvalidData)),
|
||||
_ => {
|
||||
let status = PodmanIdeStatus {
|
||||
ide_state: IdeState::OPENING,
|
||||
};
|
||||
let listen_port = self
|
||||
.list
|
||||
.container
|
||||
.iter()
|
||||
.max_by_key(|i| i.ide_param.listen_port)
|
||||
.and_then(|i| Some(i.ide_param.listen_port + 1))
|
||||
.or(Some(3000))
|
||||
.unwrap();
|
||||
let ide_param = NixIdeServerParam {
|
||||
listen_address: default_listen_address(),
|
||||
listen_port: listen_port,
|
||||
app_folder: default_app_folder(),
|
||||
project_folder: default_project_folder(),
|
||||
working_folder: default_working_folder(),
|
||||
};
|
||||
fn start_open(&self, ide_id: &str, param: &OpenGitParam) -> Result<IdeState, Status> {
|
||||
let mut eng = PodmanEngine::reload(self)
|
||||
.map_err(|_| Status::new(500, "internal error : reload engine"))?;
|
||||
match eng.list.container.iter().find(|i| i.ide_id.eq(ide_id)) {
|
||||
Some(i) => Ok(i.ide_state.clone()),
|
||||
_ => {
|
||||
let ide_folder = create_ide_folder_path(&self.working_folder, ide_id);
|
||||
fs::create_dir_all(&ide_folder)
|
||||
.map_err(|_| Status::new(500, "internal error : can't create ide folder"))?;
|
||||
let listen_port = eng
|
||||
.list
|
||||
.container
|
||||
.iter()
|
||||
.max_by_key(|i| i.ide_param.listen_port)
|
||||
.and_then(|i| Some(i.ide_param.listen_port + 1))
|
||||
.or(Some(3000))
|
||||
.unwrap();
|
||||
let ide_param = NixIdeServerParam {
|
||||
listen_address: default_listen_address(),
|
||||
listen_port,
|
||||
app_folder: default_app_folder(),
|
||||
project_folder: default_project_folder(),
|
||||
working_folder: default_working_folder(),
|
||||
};
|
||||
|
||||
let container = PodmanContainer {
|
||||
state: PodmanState::FetchingSource,
|
||||
ide_param,
|
||||
};
|
||||
self.list.container.push(container);
|
||||
self.save()?;
|
||||
file.write(serde_json::to_string_pretty(&status)?.as_bytes())?;
|
||||
Ok(status.ide_state)
|
||||
let container = PodmanContainer {
|
||||
ide_id: ide_id.to_owned(),
|
||||
ide_state: IdeState::OPENING,
|
||||
state: PodmanState::FetchingSource,
|
||||
ide_param,
|
||||
};
|
||||
eng.list.container.push(container);
|
||||
eng.save()
|
||||
.map_err(|_| Status::new(500, "internal error: can't save curent state"))?;
|
||||
|
||||
fetch_sources(&format!("{}/repo", ide_folder), param)
|
||||
.map_err(|_| Status::new(500, "internal error"))?;
|
||||
match eng.list.container.iter_mut().find(|i| i.ide_id.eq(ide_id)) {
|
||||
Some(i) => {
|
||||
i.state = PodmanState::StartingContainer;
|
||||
eng.save().map_err(|_| {
|
||||
Status::new(500, "internal error: can't save curent state")
|
||||
})?;
|
||||
}
|
||||
}
|
||||
})
|
||||
.map_err(|_| Status::new(500, "internal error"))
|
||||
_ => {}
|
||||
};
|
||||
|
||||
Ok(IdeState::OPENING)
|
||||
}
|
||||
}
|
||||
|
||||
// println!("foo {:x}", hash);
|
||||
// let out = Command::new("podman")
|
||||
// .arg("create")
|
||||
@@ -188,24 +210,10 @@ fn default_working_folder() -> String {
|
||||
"$PWD".to_owned()
|
||||
}
|
||||
|
||||
fn create_state_file_path(working_folder_path: &Path, ide_id: &str) -> String {
|
||||
let ide_folder = format!("{}/{}", working_folder_path.display(), ide_id);
|
||||
create_state_file_path_from_ide_folder(&ide_folder)
|
||||
}
|
||||
|
||||
fn create_state_file_path_from_ide_folder(ide_folder: &str) -> String {
|
||||
format!("{}/.ide_state", ide_folder)
|
||||
}
|
||||
|
||||
fn create_ide_folder_path(working_folder_path: &Path, ide_id: &str) -> String {
|
||||
format!("{}/{}", working_folder_path.display(), ide_id)
|
||||
}
|
||||
|
||||
fn read_ide_state(json_string: &str) -> Result<IdeState, serde_json::Error> {
|
||||
let status: PodmanIdeStatus = serde_json::from_str(json_string)?;
|
||||
Ok(status.ide_state)
|
||||
}
|
||||
|
||||
fn read_from_list_file(path: &str) -> Result<PodmanContainerList, std::io::Error> {
|
||||
match fs::read_to_string(path) {
|
||||
Ok(json_string) => serde_json::from_str::<PodmanContainerList>(&json_string)
|
||||
@@ -213,3 +221,35 @@ fn read_from_list_file(path: &str) -> Result<PodmanContainerList, std::io::Error
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_sources(repo_path: &str, param: &OpenGitParam) -> Result<(), std::io::Error> {
|
||||
Command::new("git")
|
||||
.arg("clone")
|
||||
.arg("-n")
|
||||
.arg(¶m.clone_url)
|
||||
.arg(repo_path)
|
||||
.output()?;
|
||||
|
||||
Command::new("git")
|
||||
.arg("-C")
|
||||
.arg(repo_path)
|
||||
.arg("checkout")
|
||||
.arg(¶m.ref_name)
|
||||
.output()
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fetch_sources() {
|
||||
let now = std::time::SystemTime::now()
|
||||
.duration_since(std::time::SystemTime::UNIX_EPOCH)
|
||||
.unwrap();
|
||||
let temp_dir = std::env::temp_dir();
|
||||
let repo_path = format!("{}/{}", temp_dir.display(), now.as_secs());
|
||||
let git_param = OpenGitParam {
|
||||
clone_url: "https://github.com/jmesmon/rust-hello-world.git".to_owned(),
|
||||
inquirer: "stubbfel".to_owned(),
|
||||
ref_name: "master".to_owned(),
|
||||
};
|
||||
assert_eq!(fetch_sources(&repo_path, &git_param).unwrap(), ());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user