Skip to content
This repository has been archived by the owner on Aug 1, 2022. It is now read-only.

Commit

Permalink
fix(proxy): project init (#727)
Browse files Browse the repository at this point in the history
* Add check that the directory exists

* Build project path

Before this change we would accept the path provided as the destination
for the project to be set up. But since the user inputs a name it would
be a better UX if they picked the base directory, i.e. some workspace,
and the project's name serves as the directory.

However, if the user is selecting a directory that already ends in the
name, then we should just take that as the path.

* Remove test_ prefixes

In coco/peer.rs test module we're prefixing with 'test_'. This is
redundant because of the 'mod test'.

* Add test for creating a project where the path ends in the same name

* Fix cannot_create_project_twice

The test was checking if the existing remote path was the root repo_path
rather than the project path.

* Project Creation

This commit splits project creation off from the peer logic. The change
captures that there are two ways to create a project in Upstream.
There's a completely new repository, or an existing repository.
In the former we expect slightly different inputs, where we build the final
directory from the supplied path and name.
In the later, we expect the existing directory to already be a git
repostiory and the last portion of the path is the name of the project.
The intention now needs to be set when creating a project via the HTTP
endpoint, instead of making guess work.

Included in this is some general refactoring of the control code which
seemed useful to have for testing.

* Renaming and cleanup

Renamed ProjectCreation to Create and RepoCreate to Repo. We then use
qualified imports elsewhere.
Run clippy and following suggestions for clean up and documentation.

* Update frontend

We match the API call on the front end to specify whether we want to
create a new or existing repository.
If existing is selected then we take the name of the folder as the name
of the project and disable the input box.
There's no behavioural change for creating a brand new project.

* Add disabled input styles

* Update spec

* Add spec for clearing name input

* RepoType enum

To avoid the wild west of JS consts, we use a TS enum to represent the
two types of Repos, existing and new. We can then use these values
instead of the plain ol' strings.

Co-authored-by: Rūdolfs Ošiņš <rudolfs@osins.org>
  • Loading branch information
FintanH and rudolfs committed Aug 12, 2020
1 parent 30d80e0 commit 9e6fd78
Show file tree
Hide file tree
Showing 12 changed files with 537 additions and 220 deletions.
17 changes: 15 additions & 2 deletions cypress/integration/project_creation.spec.js
Expand Up @@ -199,6 +199,15 @@ context("project creation", () => {
});

context("form", () => {
it("clears name input when switching from new to existing project", () => {
cy.pick("name").clear();
cy.pick("name").type("this-will-be-a-new-project");
cy.pick("new-project").click();
cy.pick("name").should("have.value", "this-will-be-a-new-project");
cy.pick("existing-project").click();
cy.pick("name").should("have.value", "");
});

it("prevents the user from submitting invalid data", () => {
// shows a validation message when new project path is empty
cy.pick("page", "new-project")
Expand Down Expand Up @@ -262,15 +271,19 @@ context("project creation", () => {
cy.pick("profile-context-menu").click();
cy.pick("dropdown-menu", "new-project").click();

cy.pick("name").type("git-platinum-copy");
cy.pick("description").type("Best project");
cy.pick("name").should("not.be.disabled");

cy.pick("existing-project").click();
cy.pick("name").should("be.disabled");

cy.pick("existing-project", "choose-path-button").click();
// Make sure UI has time to update path value from stub,
// this prevents this spec from failing on CI.
cy.wait(500);

cy.pick("name").should("have.value", "git-platinum-copy");
cy.pick("description").type("Best project");

cy.pick("create-project-button").click();
cy.pick("project-screen", "topbar", "project-avatar").contains(
"git-platinum-copy"
Expand Down
2 changes: 2 additions & 0 deletions proxy/src/coco.rs
Expand Up @@ -13,6 +13,8 @@ pub mod control;
mod peer;
pub use peer::{verify_user, Api, User};

pub mod project;

mod source;
pub use source::{
blob, branches, commit, commit_header, commits, into_branch_type, local_state, revisions, tags,
Expand Down
61 changes: 40 additions & 21 deletions proxy/src/coco/control.rs
Expand Up @@ -2,12 +2,15 @@

use std::convert::TryFrom;
use std::env;
use std::io;
use std::path;

use librad::keys;
use librad::meta::entity;
use librad::meta::project;
use radicle_surf::vcs::git::git2;

use crate::coco;
use crate::coco::config;
use crate::coco::peer::{Api, User};
use crate::error;
Expand Down Expand Up @@ -74,27 +77,22 @@ pub fn replicate_platinum(
description: &str,
default_branch: &str,
) -> Result<project::Project<entity::Draft>, error::Error> {
// Craft the absolute path to git-platinum fixtures.
let mut platinum_path = env::current_dir()?;
platinum_path.push("../fixtures/git-platinum");
let mut platinum_from = String::from("file://");
platinum_from.push_str(platinum_path.to_str().expect("unable get path"));

// Construct path for fixtures to clone into.
let monorepo = api.monorepo();
let workspace = monorepo.join("../workspace");
let platinum_into = workspace.join(name);

clone_platinum(&platinum_from, &platinum_into)?;
clone_platinum(&platinum_into)?;

let project_creation = coco::project::Create {
description: description.to_string(),
default_branch: default_branch.to_string(),
repo: coco::project::Repo::Existing {
path: platinum_into.clone(),
},
};

let meta = api.init_project(
key,
owner,
platinum_into.clone(),
name,
description,
default_branch,
)?;
let meta = api.init_project(key, owner, project_creation)?;

// Push branches and tags.
{
Expand Down Expand Up @@ -125,6 +123,17 @@ pub fn replicate_platinum(
Ok(meta)
}

/// Craft the absolute path to git-platinum fixtures.
///
/// # Errors
///
/// * Failed to get current directory
pub fn platinum_directory() -> io::Result<path::PathBuf> {
let mut platinum_path = env::current_dir()?;
platinum_path.push("../fixtures/git-platinum");
Ok(path::Path::new("file://").join(platinum_path))
}

/// Create and track a fake peer.
#[must_use]
pub fn track_fake_peer(
Expand Down Expand Up @@ -209,19 +218,29 @@ pub fn track_fake_peer(

/// This function exists as a standalone because the logic does not play well with async in
/// `replicate_platinum`.
fn clone_platinum(
platinum_from: &str,
platinum_into: &std::path::PathBuf,
) -> Result<(), error::Error> {
///
/// # Errors
///
/// * Cloning the repository failed
/// * We could not fetch branches
///
/// # Panics
///
/// * The platinum directory path was malformed
/// * Getting the branches fails
pub fn clone_platinum(platinum_into: impl AsRef<path::Path>) -> Result<(), error::Error> {
let platinum_from = platinum_directory()?;
let platinum_from = platinum_from
.to_str()
.expect("failed to get platinum directory");
let mut fetch_options = git2::FetchOptions::new();
fetch_options.download_tags(git2::AutotagOption::All);

let platinum_repo = git2::build::RepoBuilder::new()
.branch("master")
.clone_local(git2::build::CloneLocal::Auto)
.fetch_options(fetch_options)
.clone(platinum_from, platinum_into.as_path())
.expect("unable to clone fixtures repo");
.clone(platinum_from, platinum_into.as_ref())?;

{
let branches = platinum_repo.branches(Some(git2::BranchType::Remote))?;
Expand Down

0 comments on commit 9e6fd78

Please sign in to comment.