Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Give more control over `init` announcement
Alexis Sellier committed 3 years ago
commit e69be6051d9178a2a626f02e04e13f21114178d0
parent 8c22012d61597e39e05342bf36b450bae4b7d341
11 files changed +86 -50
modified radicle-cli/examples/rad-init-sync.md
@@ -3,7 +3,7 @@ To create your first radicle project, navigate to a git repository, and run
the `init` command:

```
-
$ rad init --name heartwood --description "Radicle Heartwood Protocol & Stack" --no-confirm
+
$ rad init --name heartwood --description "Radicle Heartwood Protocol & Stack" --no-confirm --announce

Initializing local 🌱 project in .

@@ -14,11 +14,9 @@ Initializing local 🌱 project in .
  "defaultBranch": "master"
}
✓ Syncing inventory..
+
✓ Announcing inventory..

Your project id is rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji. You can show it any time by running:
    rad .

-
To publish your project to the network, run:
-
    rad push
-

```
modified radicle-cli/examples/rad-init.md
@@ -3,7 +3,7 @@ To create your first radicle project, navigate to a git repository, and run
the `init` command:

```
-
$ rad init --name heartwood --description "Radicle Heartwood Protocol & Stack" --no-confirm --no-sync --no-track
+
$ rad init --name heartwood --description "Radicle Heartwood Protocol & Stack" --no-confirm --no-track

Initializing local 🌱 project in .

modified radicle-cli/src/commands/init.rs
@@ -33,8 +33,8 @@ Options
    --default-branch     The default branch of the project
    --set-upstream, -u   Setup the upstream of the default branch
    --setup-signing      Setup the radicle key as a signing key for this repository
+
    --announce           Announce the new project to the network
    --no-confirm         Don't ask for confirmation during setup
-
    --no-sync            Don't announce the new project to the network
    --help               Print help
"#,
};
@@ -48,7 +48,7 @@ pub struct Options {
    pub interactive: Interactive,
    pub setup_signing: bool,
    pub set_upstream: bool,
-
    pub sync: bool,
+
    pub announce: bool,
    pub track: bool,
}

@@ -65,7 +65,7 @@ impl Args for Options {
        let mut interactive = Interactive::Yes;
        let mut set_upstream = false;
        let mut setup_signing = false;
-
        let mut sync = true;
+
        let mut announce = false;
        let mut track = true;

        while let Some(arg) = parser.next()? {
@@ -108,15 +108,12 @@ impl Args for Options {
                Long("setup-signing") => {
                    setup_signing = true;
                }
+
                Long("announce") => {
+
                    announce = true;
+
                }
                Long("no-confirm") => {
                    interactive = Interactive::No;
                }
-
                Long("sync") => {
-
                    sync = true;
-
                }
-
                Long("no-sync") => {
-
                    sync = false;
-
                }
                Long("no-track") => {
                    track = false;
                }
@@ -139,7 +136,7 @@ impl Args for Options {
                interactive,
                set_upstream,
                setup_signing,
-
                sync,
+
                announce,
                track,
            },
            vec![],
@@ -241,7 +238,8 @@ pub fn init(options: Options, profile: &profile::Profile) -> anyhow::Result<()>
                // Setup radicle signing key.
                self::setup_signing(profile.id(), &repo, interactive)?;
            }
-
            if options.sync {
+

+
            if node.is_running() {
                let spinner = term::spinner("Syncing inventory..");
                if let Err(e) = node.sync_inventory() {
                    spinner.error(e);
@@ -250,6 +248,15 @@ pub fn init(options: Options, profile: &profile::Profile) -> anyhow::Result<()>
                }
            }

+
            if options.announce {
+
                let spinner = term::spinner("Announcing inventory..");
+
                if let Err(e) = node.announce_inventory() {
+
                    spinner.error(e);
+
                } else {
+
                    spinner.finish();
+
                }
+
            }
+

            term::blank();
            term::info!(
                "Your project id is {}. You can show it any time by running:",
@@ -257,9 +264,11 @@ pub fn init(options: Options, profile: &profile::Profile) -> anyhow::Result<()>
            );
            term::indented(term::format::secondary("rad ."));

-
            term::blank();
-
            term::info!("To publish your project to the network, run:");
-
            term::indented(term::format::secondary("rad push"));
+
            if !options.announce {
+
                term::blank();
+
                term::info!("To publish your project to the network, run:");
+
                term::indented(term::format::secondary("rad push"));
+
            }
            term::blank();
        }
        Err(err) => {
modified radicle-cli/src/commands/push.rs
@@ -15,15 +15,13 @@ pub const HELP: Help = Help {
    usage: r#"
Usage

-
    rad push [--all] [--[no-]sync] [<option>...]
+
    rad push [--all] [<option>...]

-
    By default, only the current branch is synced.
+
    By default, only the current branch is pushed.

Options

    --all               Push all branches (default: false)
-
    --sync              Sync after pushing to the "rad" remote (default: false)
-
    --no-sync           Do not sync after pushing to the "rad" remote
    --help              Print help

Git options
@@ -40,7 +38,6 @@ pub struct Options {
    pub force: bool,
    pub all: bool,
    pub set_upstream: bool,
-
    pub sync: bool,
}

impl Args for Options {
@@ -51,7 +48,6 @@ impl Args for Options {
        let mut verbose = false;
        let mut force = false;
        let mut all = false;
-
        let mut sync = None;
        let mut set_upstream = false;

        while let Some(arg) = parser.next()? {
@@ -68,16 +64,6 @@ impl Args for Options {
                Long("set-upstream") | Short('u') => {
                    set_upstream = true;
                }
-
                Long("sync") => {
-
                    // Falls back to `--no-sync` in case of ambiguity.
-
                    // eg. `rad push --no-sync --sync`
-
                    if sync.is_none() {
-
                        sync = Some(true);
-
                    }
-
                }
-
                Long("no-sync") => {
-
                    sync = Some(false);
-
                }
                Long("force") | Short('f') => {
                    force = true;
                }
@@ -92,7 +78,6 @@ impl Args for Options {
                force,
                all,
                set_upstream,
-
                sync: sync.unwrap_or_default(),
                verbose,
            },
            vec![],
@@ -130,9 +115,5 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
        Err(err) => return Err(err.into()),
    }

-
    if options.sync {
-
        term::warning("the `--sync` option is not yet supported");
-
    }
-

    Ok(())
}
modified radicle-cli/tests/commands.rs
@@ -388,6 +388,7 @@ fn test_replication_via_seed() {
                "Radicle Heartwood Protocol & Stack",
                "--default-branch",
                "master",
+
                "--announce",
            ],
            working.join("alice"),
        )
modified radicle-httpd/src/test.rs
@@ -95,7 +95,7 @@ pub fn seed(dir: &Path) -> Context {
            interactive: false.into(),
            setup_signing: false,
            set_upstream: false,
-
            sync: false,
+
            announce: false,
            track: false,
        },
        &profile,
modified radicle-node/src/control.rs
@@ -165,6 +165,12 @@ fn command<H: Handle<Error = runtime::HandleError>>(
            }
            CommandResult::ok().to_writer(writer).ok();
        }
+
        CommandName::AnnounceInventory => {
+
            if let Err(e) = handle.announce_inventory() {
+
                return Err(CommandError::Runtime(e));
+
            }
+
            CommandResult::ok().to_writer(writer).ok();
+
        }
        CommandName::SyncInventory => match handle.sync_inventory() {
            Ok(updated) => {
                CommandResult::Okay { updated }.to_writer(writer)?;
modified radicle-node/src/runtime/handle.rs
@@ -159,6 +159,10 @@ impl<G: Signer + Ecdh + 'static> radicle::node::Handle for Handle<G> {
        self.command(service::Command::AnnounceRefs(id))
    }

+
    fn announce_inventory(&mut self) -> Result<(), Error> {
+
        self.command(service::Command::AnnounceInventory)
+
    }
+

    fn sync_inventory(&mut self) -> Result<bool, Error> {
        let (sender, receiver) = chan::bounded(1);
        self.command(service::Command::SyncInventory(sender))?;
modified radicle-node/src/service.rs
@@ -104,6 +104,8 @@ pub type QueryState = dyn Fn(&dyn ServiceState) -> Result<(), CommandError> + Se
pub enum Command {
    /// Announce repository references for given repository to peers.
    AnnounceRefs(Id),
+
    /// Announce local repositories to peers.
+
    AnnounceInventory,
    /// Announce local inventory to peers.
    SyncInventory(chan::Sender<bool>),
    /// Connect to node with the given address.
@@ -128,6 +130,7 @@ impl fmt::Debug for Command {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::AnnounceRefs(id) => write!(f, "AnnounceRefs({id})"),
+
            Self::AnnounceInventory => write!(f, "AnnounceInventory"),
            Self::SyncInventory(_) => write!(f, "SyncInventory(..)"),
            Self::Connect(id, addr) => write!(f, "Connect({id}, {addr})"),
            Self::Seeds(id, _) => write!(f, "Seeds({id})"),
@@ -516,10 +519,19 @@ where
                    error!("Error announcing refs: {}", err);
                }
            }
+
            Command::AnnounceInventory => {
+
                if let Err(err) = self
+
                    .storage
+
                    .inventory()
+
                    .and_then(|i| self.announce_inventory(i))
+
                {
+
                    error!("Error announcing inventory: {}", err);
+
                }
+
            }
            Command::SyncInventory(resp) => {
                let updated = self
-
                    .sync_and_announce_inventory()
-
                    .expect("Service::command: error syncing and announcing inventory");
+
                    .sync_inventory()
+
                    .expect("Service::command: error syncing inventory");
                resp.send(!updated.is_empty()).ok();
            }
            Command::QueryState(query, sender) => {
@@ -620,8 +632,21 @@ where
            // cases.

            // Announce the newly fetched repository to the network, if necessary.
-
            if let Err(e) = self.sync_and_announce_inventory() {
-
                error!(target: "service", "Failed to sync announce new inventory: {e}");
+
            match self.sync_inventory() {
+
                Ok(updated) => {
+
                    if !updated.is_empty() {
+
                        if let Err(e) = self
+
                            .storage
+
                            .inventory()
+
                            .and_then(|i| self.announce_inventory(i))
+
                        {
+
                            error!(target: "service", "Failed to announce inventory: {e}");
+
                        }
+
                    }
+
                }
+
                Err(e) => {
+
                    error!(target: "service", "Failed to sync inventory: {e}");
+
                }
            }
        }

@@ -1073,13 +1098,10 @@ where
    }

    /// Sync, and if needed, announce our local inventory.
-
    fn sync_and_announce_inventory(&mut self) -> Result<Vec<Id>, Error> {
+
    fn sync_inventory(&mut self) -> Result<Vec<Id>, Error> {
        let inventory = self.storage.inventory()?;
        let updated = self.sync_routing(&inventory, self.node_id(), self.time())?;

-
        if !updated.is_empty() {
-
            self.announce_inventory(inventory)?;
-
        }
        Ok(updated)
    }

modified radicle-node/src/test/handle.rs
@@ -59,6 +59,10 @@ impl radicle::node::Handle for Handle {
        Ok(())
    }

+
    fn announce_inventory(&mut self) -> Result<(), Self::Error> {
+
        Ok(())
+
    }
+

    fn sync_inventory(&mut self) -> Result<bool, Self::Error> {
        unimplemented!()
    }
modified radicle/src/node.rs
@@ -110,6 +110,8 @@ impl From<net::SocketAddr> for Address {
pub enum CommandName {
    /// Announce repository references for given repository to peers.
    AnnounceRefs,
+
    /// Announce local repositories to peers.
+
    AnnounceInventory,
    /// Sync local inventory with node.
    SyncInventory,
    /// Connect to node with the given address.
@@ -382,8 +384,10 @@ pub trait Handle {
    fn untrack_repo(&mut self, id: Id) -> Result<bool, Self::Error>;
    /// Untrack the given node.
    fn untrack_node(&mut self, id: NodeId) -> Result<bool, Self::Error>;
-
    /// Notify the service that a project has been updated.
+
    /// Notify the service that a project has been updated, and announce local refs.
    fn announce_refs(&mut self, id: Id) -> Result<(), Self::Error>;
+
    /// Announce local inventory.
+
    fn announce_inventory(&mut self) -> Result<(), Self::Error>;
    /// Notify the service that our inventory was updated.
    fn sync_inventory(&mut self) -> Result<bool, Self::Error>;
    /// Ask the service to shutdown.
@@ -525,6 +529,13 @@ impl Handle for Node {
        Ok(())
    }

+
    fn announce_inventory(&mut self) -> Result<(), Error> {
+
        for line in self.call::<&str, CommandResult>(CommandName::AnnounceInventory, [])? {
+
            line?;
+
        }
+
        Ok(())
+
    }
+

    fn sync_inventory(&mut self) -> Result<bool, Error> {
        let mut line = self.call::<&str, _>(CommandName::SyncInventory, [])?;
        let response: CommandResult = line.next().ok_or(Error::EmptyResponse {