elvsc

19 commits
Updated 2026-04-30 16:50:05
src/commands/update
src/commands/update/repo.rs
use crate::{ElvscArgs, commands::update::hub::get_hub_summaries};

use std::path::Path;

use jj_cli::{cli_util::CommandHelper, command_error::CommandError, ui::Ui};
use jj_lib::{ref_name::RemoteNameBuf, repo::Repo};

pub mod tree;

pub async fn run(ui: &mut Ui, ch: &CommandHelper) -> Result<(), CommandError> {
    let args = ElvscArgs::from_config(ch)?;
    let tmp = tempfile::tempdir()?;
    let repositories = get_hub_summaries(&(&args.hub).into())?;

    super::hub::write_frontend(tmp.path(), &args.public, &repositories)?;
    super::hub::write_assets(tmp.path())?;

    let delete = write_frontend(
        &tmp.path().join(&args.repo),
        ui,
        ch,
        &args.repo,
        &args.remote,
        &args.public,
    )
    .await?;

    super::rsync(ui, tmp.path(), &args.output, Some((&args.repo, &delete)))
}

async fn write_frontend(
    output: &Path,
    ui: &mut Ui,
    ch: &CommandHelper,
    repo: &str,
    remote: &str,
    public: &str,
) -> Result<Vec<String>, CommandError> {
    std::fs::create_dir_all(&output)?;
    let wch = ch.workspace_helper(ui)?;

    let mut selected_bookmark = None;
    let mut written_bookmarks = Vec::with_capacity(16);

    let bookmarks: Vec<_> = wch
        .repo()
        .view()
        .remote_bookmarks(&RemoteNameBuf::from(remote))
        .flat_map(|(name, target)| {
            let bookmark = name.as_str().to_string();

            written_bookmarks.push(bookmark.clone());

            if let Some(id) = target.tracked_target().as_normal() {
                if name.as_str() == "trunk" {
                    selected_bookmark.replace(bookmark.clone());
                } else if name.as_str() == "main" {
                    if selected_bookmark.as_deref() != Some("trunk") {
                        selected_bookmark.replace(bookmark.clone());
                    }
                } else if selected_bookmark.is_none() {
                    selected_bookmark.replace(bookmark.clone());
                }

                Some((bookmark, id.clone()))
            } else {
                None
            }
        })
        .collect();

    for (bookmark, id) in &bookmarks {
        let commit = wch.repo().store().get_commit(id)?;

        tree::write_frontend(
            &output.join(&bookmark).join("tree"),
            ui,
            ch,
            repo,
            public,
            &bookmark,
            &written_bookmarks,
            commit,
        )
        .await?;

        std::fs::copy(
            output.join(&bookmark).join("tree").join("index.html"),
            output.join(&bookmark).join("index.html"),
        )?;
    }

    if let Some(bookmark) = selected_bookmark {
        std::fs::copy(
            output.join(&bookmark).join("index.html"),
            output.join("index.html"),
        )?;
    }

    Ok(written_bookmarks)
}