1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! Functions for invoking the CLI imperatively

pub mod cli;
pub mod commands;
pub mod content;
pub mod extension;
pub mod paths;
pub mod render;
pub mod workspace;

use anyhow::Result;

use noosphere_core::tracing::initialize_tracing;

use clap::Parser;

use self::{
    cli::{AuthCommand, Cli, ConfigCommand, FollowCommand, KeyCommand, OrbCommand, SphereCommand},
    commands::{
        key::{key_create, key_list},
        serve::serve,
        sphere::{
            auth_add, auth_list, auth_revoke, config_get, config_set, follow_add, follow_list,
            follow_remove, follow_rename, history, save, sphere_create, sphere_join, status, sync,
        },
    },
    workspace::Workspace,
};

#[cfg(not(doc))]
#[allow(missing_docs)]
pub async fn main() -> Result<()> {
    initialize_tracing(None);

    let workspace = Workspace::new(&std::env::current_dir()?, None)?;

    invoke_cli(Cli::parse(), workspace).await
}

/// Invoke the CLI implementation imperatively. This is the entrypoint used by
/// orb when handling a command line invocation. The [Cli] is produced by
/// parsing the command line arguments, and the [Workspace] is initialized from
/// the current working directory. The effect of invoking the CLI this way will
/// depend on the [Cli] and [Workspace] provided (results may vary significantly
/// depending on those inputs).
pub async fn invoke_cli(cli: Cli, mut workspace: Workspace) -> Result<()> {
    match cli.command {
        OrbCommand::Key { command } => match command {
            KeyCommand::Create { name } => key_create(&name, &workspace).await?,
            KeyCommand::List { as_json } => key_list(as_json, &workspace).await?,
        },
        OrbCommand::Sphere { command } => match command {
            SphereCommand::Create { owner_key } => {
                sphere_create(&owner_key, &mut workspace).await?;
            }
            SphereCommand::Join {
                local_key,
                authorization,
                id,
                gateway_url,
                render_depth,
            } => {
                sphere_join(
                    &local_key,
                    authorization,
                    &id,
                    &gateway_url,
                    render_depth,
                    &mut workspace,
                )
                .await?;
            }
            SphereCommand::Auth { command } => match command {
                AuthCommand::Add { did, name } => {
                    auth_add(&did, name, &workspace).await?;
                }
                AuthCommand::List { tree, as_json } => auth_list(tree, as_json, &workspace).await?,
                AuthCommand::Revoke { name } => auth_revoke(&name, &workspace).await?,
                AuthCommand::Rotate {} => unimplemented!(),
            },
            SphereCommand::Config { command } => match command {
                ConfigCommand::Set { command } => config_set(command, &workspace).await?,
                ConfigCommand::Get { command } => config_get(command, &workspace).await?,
            },

            SphereCommand::Status { id } => status(id, &workspace).await?,
            SphereCommand::Save { render_depth } => save(render_depth, &workspace).await?,
            SphereCommand::Sync {
                auto_retry,
                render_depth,
            } => sync(auto_retry, render_depth, &workspace).await?,
            SphereCommand::Follow { command } => match command {
                FollowCommand::Add { name, sphere_id } => {
                    follow_add(name, sphere_id, &workspace).await?;
                }
                FollowCommand::Remove {
                    by_name,
                    by_sphere_id,
                } => follow_remove(by_name, by_sphere_id, &workspace).await?,
                FollowCommand::Rename { from, to } => follow_rename(from, to, &workspace).await?,
                FollowCommand::List { as_json } => follow_list(as_json, &workspace).await?,
            },
            SphereCommand::Render { render_depth } => {
                commands::sphere::render(render_depth, &workspace).await?
            }
            SphereCommand::History => {
                history(&workspace).await?;
            }
        },

        OrbCommand::Serve {
            cors_origin,
            ipfs_api,
            name_resolver_api,
            interface,
            port,
        } => {
            serve(
                interface,
                port,
                ipfs_api,
                name_resolver_api,
                cors_origin,
                &workspace,
            )
            .await?
        }
    };

    Ok(())
}