Skip to content
Open
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
16 changes: 13 additions & 3 deletions crates/app/src/bin/workflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use app::cli::{DiffCommand, RollbackCommand};
use app::{
bootstrap::{get_alias_service, get_logger_manager},
cli::{
AliasCommand, BranchSubcommand, Cli, Command, CompletionCommand, GithubCommand,
IgnoreSubcommand, JiraCommand, LlmCommand, LogCommand, PrSubcommand, RepoCommand,
SshCommand, StashSubcommand, TagSubcommand, UninstallArgs, UpdateArgs,
AliasCommand, BranchSubcommand, Cli, CodeupCommand, Command, CompletionCommand,
GithubCommand, IgnoreSubcommand, JiraCommand, LlmCommand, LogCommand, PrSubcommand,
RepoCommand, SshCommand, StashSubcommand, TagSubcommand, UninstallArgs, UpdateArgs,
},
commands,
};
Expand Down Expand Up @@ -127,6 +127,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
cmd.run()?;
}
},
Command::Codeup(codeup_cmd) => match codeup_cmd {
CodeupCommand::Check => {
let cmd = commands::codeup::CodeupCheckCommand::new();
cmd.run()?;
}
CodeupCommand::Setup => {
let cmd = commands::codeup::CodeupSetupCommand::new();
cmd.run()?;
}
},
Command::Jira(jira_cmd) => match jira_cmd {
JiraCommand::Check => {
let cmd = commands::jira::JiraCheckCommand::new();
Expand Down
64 changes: 64 additions & 0 deletions crates/app/src/bootstrap/context/codeup_context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//! Codeup 配置上下文实现
//!
//! 实现 `client::codeup::context::CodeupConfigContext` trait,
//! 提供配置获取逻辑。

use std::sync::Arc;

use client::{CodeupClientError, CodeupConfigContext};
use domain::GlobalConfigRepository;

/// Codeup 配置上下文实现
///
/// 实现 `CodeupConfigContext` trait,提供基于配置适配器的配置获取逻辑。
pub struct CodeupContextImpl {
config: Arc<dyn GlobalConfigRepository>,
}

impl CodeupContextImpl {
pub fn new(config: Arc<dyn GlobalConfigRepository>) -> Self {
Self { config }
}

/// 获取 Codeup 配置
fn get_codeup_settings(&self) -> Result<domain::CodeupSettings, CodeupClientError> {
let config = self
.config
.load()
.map_err(|e| CodeupClientError::ConfigError(format!("加载配置失败: {}", e)))?;
Ok(config.codeup)
}
}

// 实现 client 层的 CodeupConfigContext
impl CodeupConfigContext for CodeupContextImpl {
fn get_project_id(&self) -> Result<String, CodeupClientError> {
let settings = self.get_codeup_settings()?;
if settings.project_id.is_empty() {
return Err(CodeupClientError::ConfigError(
"Codeup project_id 未配置".to_string(),
));
}
Ok(settings.project_id)
}

fn get_csrf_token(&self) -> Result<String, CodeupClientError> {
let settings = self.get_codeup_settings()?;
if settings.csrf_token.is_empty() {
return Err(CodeupClientError::ConfigError(
"Codeup csrf_token 未配置".to_string(),
));
}
Ok(settings.csrf_token)
}

fn get_cookie(&self) -> Result<String, CodeupClientError> {
let settings = self.get_codeup_settings()?;
if settings.cookie.is_empty() {
return Err(CodeupClientError::ConfigError(
"Codeup cookie 未配置".to_string(),
));
}
Ok(settings.cookie)
}
}
11 changes: 10 additions & 1 deletion crates/app/src/bootstrap/context/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
mod codeup_context;
mod github_context;
mod jira_context;
mod llm_context;

use std::sync::Arc;

use client::{GitHubConfigContext, JiraConfigContext, LLMConfigContext};
use client::{CodeupConfigContext, GitHubConfigContext, JiraConfigContext, LLMConfigContext};
use di::{bind, Container, InjectionError, Scope};
use domain::{GlobalConfigRepository, PathService};

pub use codeup_context::CodeupContextImpl;
pub use github_context::GitHubContextImpl;
pub use jira_context::JiraConfigContextImpl;
pub use llm_context::LLMConfigContextImpl;
Expand Down Expand Up @@ -44,5 +46,12 @@ pub fn register_context() -> Result<(), InjectionError> {
})
.in_scope(Scope::Singleton)?;

// Codeup Config Context
bind!(dyn CodeupConfigContext, |c: &Container| {
let global_config = c.get::<dyn GlobalConfigRepository>()?;
Ok(Arc::new(CodeupContextImpl::new(global_config)))
})
.in_scope(Scope::Singleton)?;

Ok(())
}
9 changes: 7 additions & 2 deletions crates/app/src/bootstrap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use std::sync::{Arc, LazyLock};

use client::LanguageManager;
use domain::{
AliasService, BranchService, CommitMessageService, CommitSummaryService, CompletionService,
GitHubRepository, GitRepository, GlobalConfigRepository, JiraRepository,
AliasService, BranchService, CodeupRepository, CommitMessageService, CommitSummaryService,
CompletionService, GitHubRepository, GitRepository, GlobalConfigRepository, JiraRepository,
JiraWorkHistoryRepository, PathService, PullRequestService, RepoConfigRepository,
VerificationService,
};
Expand Down Expand Up @@ -157,6 +157,11 @@ pub fn get_github_repository() -> Arc<dyn GitHubRepository> {
get_service::<dyn GitHubRepository>()
}

/// 获取 CodeupRepository
pub fn get_codeup_repository() -> Arc<dyn CodeupRepository> {
get_service::<dyn CodeupRepository>()
}

/// 获取 JiraRepository
pub fn get_jira_repository() -> Arc<dyn JiraRepository> {
get_service::<dyn JiraRepository>()
Expand Down
4 changes: 2 additions & 2 deletions crates/app/src/commands/branch/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use domain::GitRepository;
use prompt::{error, info, input, select, spinner, success};

use crate::util::{
generate_branch_name_from_jira, generate_branch_name_from_template, select_branch_type, to_slug,
generate_branch_name_from_jira, generate_branch_name_from_template, safe_pull,
select_branch_type, to_slug, PullOptions,
};
use crate::util::{safe_pull, PullOptions};
use crate::{bootstrap, commands::jira::utils::get_jira_id_interactive_optional};

/// 源分支选项
Expand Down
4 changes: 4 additions & 0 deletions crates/app/src/commands/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub use crate::commands::diff::DiffCommand;
pub use crate::commands::rollback::RollbackCommand;
pub use crate::commands::{
branch::{BranchSubcommand, IgnoreSubcommand},
codeup::CodeupCommand,
completion::CompletionCommand,
github::GithubCommand,
jira::{AttachmentsArgs, CleanArgs, InfoArgs, JiraCommand, OutputFormat},
Expand Down Expand Up @@ -68,6 +69,9 @@ pub enum Command {
/// GitHub account management commands
#[command(subcommand)]
Github(GithubCommand),
/// Codeup configuration management commands
#[command(subcommand)]
Codeup(CodeupCommand),
/// Jira configuration management commands
#[command(subcommand)]
Jira(JiraCommand),
Expand Down
32 changes: 32 additions & 0 deletions crates/app/src/commands/codeup/check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//! 检查 Codeup 配置命令

use prompt::{br, separator};

use crate::bootstrap;
use crate::interactive::{WorkflowExecutor, CODEUP_STAGE_NAME};

/// Codeup Check 命令
pub struct CodeupCheckCommand;

impl Default for CodeupCheckCommand {
fn default() -> Self {
Self::new()
}
}

impl CodeupCheckCommand {
/// 创建新的 CodeupCheckCommand
pub fn new() -> Self {
Self
}

/// 运行 `workflow codeup check` 命令
pub fn run(&self) -> Result<(), Box<dyn std::error::Error>> {
separator!('─', 80, "Codeup Configuration Check");
br!();
let stage = bootstrap::get_workflow_stage_registry()
.stage_by_name(CODEUP_STAGE_NAME)
.expect("Codeup stage must be registered");
WorkflowExecutor::new(stage).run_verify()
}
}
14 changes: 14 additions & 0 deletions crates/app/src/commands/codeup/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Codeup 配置管理子命令
//!
//! Codeup 配置管理子命令结构定义

use clap::Subcommand;

/// Codeup 配置管理子命令
#[derive(Subcommand)]
pub enum CodeupCommand {
/// 检查 Codeup 配置(显示项目 ID、验证状态)
Check,
/// 设置 Codeup 配置(交互式配置项目 ID、CSRF Token、Cookie)
Setup,
}
9 changes: 9 additions & 0 deletions crates/app/src/commands/codeup/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//! Codeup 配置管理命令

pub mod check;
mod cli;
pub mod setup;

pub use check::CodeupCheckCommand;
pub use cli::CodeupCommand;
pub use setup::CodeupSetupCommand;
28 changes: 28 additions & 0 deletions crates/app/src/commands/codeup/setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! 设置 Codeup 配置命令

use crate::bootstrap;
use crate::interactive::{WorkflowExecutor, CODEUP_STAGE_NAME};

/// Codeup Setup 命令
pub struct CodeupSetupCommand;

impl Default for CodeupSetupCommand {
fn default() -> Self {
Self::new()
}
}

impl CodeupSetupCommand {
/// 创建新的 CodeupSetupCommand
pub fn new() -> Self {
Self
}

/// 运行 `workflow codeup setup` 命令
pub fn run(&self) -> Result<(), Box<dyn std::error::Error>> {
let stage = bootstrap::get_workflow_stage_registry()
.stage_by_name(CODEUP_STAGE_NAME)
.expect("Codeup stage must be registered");
WorkflowExecutor::new(stage).run_command_setup()
}
}
1 change: 1 addition & 0 deletions crates/app/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod rollback;
pub mod alias;
pub mod branch;
pub mod check;
pub mod codeup;
pub mod commit;
pub mod completion;
pub mod github;
Expand Down
8 changes: 7 additions & 1 deletion crates/app/src/commands/pr/create/pr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,13 @@ pub fn create_pull_request(
(Some(repo_name), Some(CodePlatform::GitHub)) => {
Some(format!("https://github.com/{}/pull/{}", repo_name, pr_id))
}
// 将来可以添加其他平台支持
(Some(_repo_name), Some(CodePlatform::Codeup)) => {
// Codeup URL 格式: https://codeup.aliyun.com/project/{project_id}/merge_request/{pr_id}
// 从 PR 服务获取实际 URL
let codeup_repo = bootstrap::get_codeup_repository();
codeup_repo.get_pull_request_url(&pr_id).ok()
}
// 其他平台支持
_ => None,
};

Expand Down
11 changes: 9 additions & 2 deletions crates/app/src/interactive/core/platform/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! 平台配置流程

use domain::GlobalConfig;
use prompt::{br, info, separator, SelectBuilder};
use prompt::{br, confirm, info, separator, SelectBuilder};

use crate::interactive::core::context::{WorkflowContext, WorkflowMode};
use crate::interactive::core::platform::{
Expand Down Expand Up @@ -66,7 +66,14 @@ where
} else {
info!("No {} accounts were detected.", platform_name);
br!();
add_account_fn(context, AccountSetMode::SetAsCurrent)?;
let should_configure = confirm!("Do you want to configure {}?", platform_name)
.default(true)
.result_title(format!("Configure {}", platform_name))
.prompt()
.map_err(|e| e.to_string())?;
if should_configure {
add_account_fn(context, AccountSetMode::SetAsCurrent)?;
}
}

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/app/src/interactive/core/stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<'a> WorkflowExecutor<'a> {
let stage_name = self.stage.stage_name();

if !self.stage.is_configured(settings) {
warning!("{} is not configured. Skipping verification.", stage_name);
// warning!("{} is not configured. Skipping verification.", stage_name);
return Ok(());
}

Expand Down
63 changes: 63 additions & 0 deletions crates/app/src/interactive/display/codeup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//! Codeup 验证结果格式化实现

use domain::{CodeupVerificationResult, CodeupVerificationStatus};
use prompt::{br, success, warning, TableBuilder, Tabled};

use crate::interactive::display::formatter::VerificationResultFormatter;

/// Codeup 配置表格行
pub struct CodeupConfigRow {
pub project_id: String,
pub csrf_token: String,
pub cookie: String,
}

impl Tabled for CodeupConfigRow {
fn headers() -> Vec<String> {
vec![
"Project ID".to_string(),
"CSRF Token".to_string(),
"Cookie".to_string(),
]
}

fn row(&self) -> Vec<String> {
vec![
self.project_id.clone(),
self.csrf_token.clone(),
self.cookie.clone(),
]
}
}

impl VerificationResultFormatter for CodeupVerificationResult {
fn format(&self) {
if !self.configured {
return;
}

if let Some(ref config) = self.config {
let row = CodeupConfigRow {
project_id: config.project_id.clone(),
csrf_token: config.csrf_token.clone(),
cookie: config.cookie.clone(),
};

let table_builder = TableBuilder::from_tabled(vec![row]);
let _ = table_builder.display();
}

if let Some(ref verification) = self.verification {
match verification {
CodeupVerificationStatus::Success { username } => {
success!("Codeup verification successful! User: {}", username);
}
CodeupVerificationStatus::Failed { reason, .. } => {
warning!("Codeup verification error: {}", reason);
}
}
}

br!();
}
}
1 change: 1 addition & 0 deletions crates/app/src/interactive/display/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! 提供验证结果的格式化显示功能,将 domain 层的验证结果转换为表格和消息输出。

mod attachment;
mod codeup;
mod formatter;
mod github;
mod jira;
Expand Down
Loading
Loading