Skip to content
Merged
Show file tree
Hide file tree
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
4 changes: 2 additions & 2 deletions .github/workflows/rust-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ jobs:

# 8️⃣ Make x.sh executable
- name: Make script executable
run: chmod +x CoTask/x.sh
run: chmod +x x.sh

# 9️⃣ Build using your custom script
- name: Build Project
run: bash CoTask/x.sh build
run: bash ./x.sh build
31 changes: 14 additions & 17 deletions src/bin/cli.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use cotask::logic::{
add_task, branch, checkout, diff, export, gc, import, init_repo, list_task, merge, rebase,
resolve, revert, show_help, show_log, stash, tag,
};
use std::env;
use cotask::logic::{add_task, branch, checkout, diff, gc, init_repo,import,export,list_task, merge, revert, show_help, show_log,resolve, rebase,stash,tag};

fn main() {
let args: Vec<String> = env::args().collect();
Expand Down Expand Up @@ -38,18 +41,16 @@ fn main() {
println!("Please provide task id.");
return;
}
let id:usize = match args[2].parse() {
let id: usize = match args[2].parse() {
Ok(n) => n,
Err(_) =>{
Err(_) => {
println!("Invalid task ID");
return;
}

};
add_task::mark_done(id);

}

"log" => show_log::show_log(),

"checkout" => {
Expand Down Expand Up @@ -99,7 +100,6 @@ fn main() {
merge::merge_branch(&args[2]);
}


"branch" => {
if args.len() < 3 {
println!("Provide branch name.");
Expand All @@ -125,7 +125,6 @@ fn main() {
}
"--help" => {
show_help::show_help();
return;
}

"tag" => {
Expand All @@ -140,7 +139,6 @@ fn main() {
tag::list_tags();
}


"resolve" => {
if args.len() < 4 {
println!("Usage: resolve <task_id> done|undone");
Expand All @@ -160,18 +158,17 @@ fn main() {
resolve::resolve(id, done);
}
"rebase" => {
if args.len() < 3 {
println!("Provide target branch.");
return;
}
if args.len() < 3 {
println!("Provide target branch.");
return;
}

rebase::rebase_onto(&args[2]);
}
rebase::rebase_onto(&args[2]);
}

_ => {
println!("Unknown command.\n");
show_help::show_help();
show_help::show_help();
}

}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub mod logic;
pub mod models;
pub mod storage;
pub mod models;
8 changes: 6 additions & 2 deletions src/logic/add_task.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::models::{commit_model::Commit, task_model::Task};
use crate::storage::{
commit::{load_commit, save_commit},
head::{read_head_branch, read_branch_commit, write_branch_commit},
head::{read_branch_commit, read_head_branch, write_branch_commit},
};

pub fn add_task(text: &str) {
Expand Down Expand Up @@ -41,7 +41,11 @@ pub fn add_task(text: &str) {
let message = format!("Added task '{}'", text);

let new_commit = Commit {
parents: if head_commit == 0 { vec![] } else { vec![head_commit] },
parents: if head_commit == 0 {
vec![]
} else {
vec![head_commit]
},
message,
tasks,
};
Expand Down
9 changes: 4 additions & 5 deletions src/logic/branch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::storage::head::{read_branch_commit, read_head_branch};
use std::fs;
use crate::storage::{commit, head::{read_branch_commit, read_head_branch}};

pub fn create_branch(name: &str) {
let current_branch = match read_head_branch() {
Expand Down Expand Up @@ -62,15 +62,14 @@ pub fn delete_branch(name: &str) {
println!("Repository not initialized.");
return;
}

};
// Prevent deleting current branch
if name == current_branch {
println!("Cannot delete the current branch '{}'.", name);
return;
}

let path = format!(".cotask/refs/{}",name);
let path = format!(".cotask/refs/{}", name);
// Check branch exists
if fs::metadata(&path).is_err() {
println!("Branch '{}' does not exist.", name);
Expand All @@ -83,5 +82,5 @@ pub fn delete_branch(name: &str) {
return;
}

println!("Branch '{}' deleted.",name);
}
println!("Branch '{}' deleted.", name);
}
12 changes: 7 additions & 5 deletions src/logic/checkout.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::fs;
use crate::logic::tag::read_tag_commit;
use crate::storage::{
commit::load_commit,
head::{write_head_branch, read_head_branch},
head::{read_head_branch, write_head_branch},
};
use crate::logic::tag::read_tag_commit;
use std::fs;

pub fn checkout_commit(commit_number: usize) {
if commit_number == 0 {
Expand All @@ -28,8 +28,10 @@ pub fn checkout_ref(name: &str) {
// 1) Branch check
let branch_path = format!(".cotask/refs/{}", name);
if fs::metadata(&branch_path).is_ok() {
if let Ok(current) = read_head_branch() {
if current == name {
if let Ok(current) = read_head_branch()
&& current == name
{
{
println!("Already on branch '{}'", name);
return;
}
Expand Down
18 changes: 9 additions & 9 deletions src/logic/diff.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashMap;
use crate::storage::commit::load_commit;
use crate::models::task_model::Task;
use crate::storage::commit::load_commit;
use std::collections::HashMap;

pub fn diff(c1: usize, c2: usize) {
let commit1 = match load_commit(c1) {
Expand Down Expand Up @@ -48,13 +48,13 @@ pub fn diff(c1: usize, c2: usize) {

// Status changes
for (id, task1) in &map1 {
if let Some(task2) = map2.get(id) {
if task1.completed != task2.completed {
if task2.completed {
println!("✓ Completed: {}. {}", task2.id, task2.text);
} else {
println!("↺ Marked incomplete: {}. {}", task2.id, task2.text);
}
if let Some(task2) = map2.get(id)
&& task1.completed != task2.completed
{
if task2.completed {
println!("✓ Completed: {}. {}", task2.id, task2.text);
} else {
println!("↺ Marked incomplete: {}. {}", task2.id, task2.text);
}
}
}
Expand Down
20 changes: 11 additions & 9 deletions src/logic/export.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use crate::{models::export_model::RepoExport, storage::commit::load_commit};
use std::{collections::HashMap, fs};
use crate::{
models::export_model::RepoExport,
storage::commit::load_commit,
};

pub fn export_repo() {
let mut commits = HashMap::new();
Expand All @@ -13,10 +10,10 @@ pub fn export_repo() {
if let Ok(entries) = fs::read_dir(".cotask/commits") {
for e in entries.flatten() {
let name = e.file_name().into_string().unwrap();
if let Ok(num) = name.trim_end_matches(".json").parse::<usize>() {
if let Ok(commit) = load_commit(num) {
commits.insert(num, commit);
}
if let Ok(num) = name.trim_end_matches(".json").parse::<usize>()
&& let Ok(commit) = load_commit(num)
{
commits.insert(num, commit);
}
}
}
Expand All @@ -43,7 +40,12 @@ pub fn export_repo() {

let head = fs::read_to_string(".cotask/HEAD").unwrap();

let export = RepoExport { commits, branches, tags, head };
let export = RepoExport {
commits,
branches,
tags,
head,
};

let json = serde_json::to_string_pretty(&export).unwrap();
fs::write("cotask_backup.json", json).unwrap();
Expand Down
16 changes: 7 additions & 9 deletions src/logic/gc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::collections::HashSet;
use std::fs;

use crate::storage::{
head::{read_head_branch, read_branch_commit},
commit::load_commit,
head::{read_branch_commit, read_head_branch},
};

fn collect_reachable(commit_number: usize, reachable: &mut HashSet<usize>) {
Expand Down Expand Up @@ -58,14 +58,12 @@ pub fn run_gc() {
let mut deleted = 0;

for entry in paths.flatten() {
if let Some(name) = entry.path().file_stem() {
if let Ok(num) = name.to_string_lossy().parse::<usize>() {
if !reachable.contains(&num) {
if fs::remove_file(entry.path()).is_ok() {
deleted += 1;
}
}
}
if let Some(name) = entry.path().file_stem()
&& let Ok(num) = name.to_string_lossy().parse::<usize>()
&& !reachable.contains(&num)
&& fs::remove_file(entry.path()).is_ok()
{
deleted += 1;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/logic/import.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fs;
use crate::models::export_model::RepoExport;
use crate::storage::commit::save_commit;
use std::fs;

pub fn import_repo(file: &str) {
let data = fs::read_to_string(file).unwrap();
Expand Down
19 changes: 6 additions & 13 deletions src/logic/init_repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,22 @@ pub fn init_repo() {
fs::create_dir(repo_path).expect("Failed to create .cotask directory");

// Create commits folder
fs::create_dir(repo_path.join("commits"))
.expect("Failed to create commits directory");
fs::create_dir(repo_path.join("commits")).expect("Failed to create commits directory");

// Create refs folder
fs::create_dir(repo_path.join("refs"))
.expect("Failed to create refs directory");
fs::create_dir(repo_path.join("refs")).expect("Failed to create refs directory");

// Create tags folder
fs::create_dir(repo_path.join("tags"))
.expect("Failed to create tags directory");
fs::create_dir(repo_path.join("tags")).expect("Failed to create tags directory");

// Create stash folder
fs::create_dir(repo_path.join("stash"))
.expect("Failed to create stash directory");

fs::create_dir(repo_path.join("stash")).expect("Failed to create stash directory");

// HEAD now stores branch name
fs::write(repo_path.join("HEAD"), "main")
.expect("Failed to create HEAD");
fs::write(repo_path.join("HEAD"), "main").expect("Failed to create HEAD");

// Create main branch pointing to commit 0
fs::write(repo_path.join("refs/main"), "0")
.expect("Failed to create main branch");
fs::write(repo_path.join("refs/main"), "0").expect("Failed to create main branch");

println!("Initialized empty cotask repository with branch 'main'.");
}
2 changes: 1 addition & 1 deletion src/logic/list_task.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::storage::{
head::{read_head_branch, read_branch_commit},
commit::load_commit,
head::{read_branch_commit, read_head_branch},
};

pub fn list_tasks() {
Expand Down
22 changes: 15 additions & 7 deletions src/logic/merge.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::fs;
use std::collections::HashMap;
use crate::models::{commit_model::Commit, task_model::Task};
use crate::storage::{
head::{read_head_branch, read_branch_commit, write_branch_commit},
commit::{load_commit, save_commit},
head::{read_branch_commit, read_head_branch, write_branch_commit},
};
use crate::models::{commit_model::Commit, task_model::Task};
use std::collections::HashMap;
use std::fs;

pub fn merge_branch(target_branch: &str) {
// Current branch (OURS)
Expand Down Expand Up @@ -43,11 +43,14 @@ pub fn merge_branch(target_branch: &str) {
let target = load_commit(theirs).unwrap();

let mut task_map: HashMap<usize, Task> = HashMap::new();
let mut conflict_found = false;

// Insert OUR tasks
for t in current.tasks {
task_map.insert(t.id, t);
}

// Merge THEIR tasks
for t in target.tasks {
task_map
.entry(t.id)
Expand All @@ -56,19 +59,24 @@ pub fn merge_branch(target_branch: &str) {
if existing.completed != t.completed || existing.text != t.text {
let conflict_info = format!(
"TASK {}\nOURS: completed={}, text={}\nTHEIRS: completed={}, text={}\n",
existing.id, existing.completed, existing.text,
t.completed, t.text
existing.id, existing.completed, existing.text, t.completed, t.text
);
fs::write(".cotask/MERGE_CONFLICT", conflict_info).unwrap();

println!("⚠ Conflict in task {}!", existing.id);
println!("Run: cotask resolve {} done|undone", existing.id);
return; // stop merge safely

conflict_found = true;
}
})
.or_insert(t);
}

// Stop merge safely if conflict happened
if conflict_found {
return;
}

let merged_tasks: Vec<Task> = task_map.into_values().collect();

let new_commit_number = ours + 1;
Expand Down
Loading