Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple packages in one repository. #38

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
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
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ A simple package manager for the Motoko programming language.
## How it works

`vessel` is inspired by the [spago](https://github.com/purescript/spago) package
manager for PureScript. Any git repository with a `src/` directory is a valid
manager for PureScript.

Any git repository with a `src/` directory is a valid
package to `vessel`, which is a flexible and lightweight approach to package
management, that is easily extended with more guarantees and features as our
community grows. The two concepts you need to understand to work with `vessel`
are _package sets_ and the _manifest_ file.

If your git repository uses a source directory other than `src/`, you can still use `vessel`
by specifying that source `path` explicitly.

### Package sets

`vessel` uses the idea of a _package set_ to manage where it pulls dependencies
Expand Down Expand Up @@ -82,6 +87,7 @@ your `additions` in the `package-set.dhall` file:
let additions = [
{ name = "mypackage"
, repo = "file:///home/path/to/mypackage"
, path = None Text
, version = "v1.0.0"
, dependencies = ["base"]
}
Expand All @@ -90,6 +96,40 @@ let additions = [

Now you can depend on this package by adding `mypackage` to your `vessel.dhall` file.


### What about *custom source paths* in a repo?

Suppose that `https://github.com/theUsername/theRepo` uses a path other than `src/` for its Motoko source code.

Assuming that the source path is `foo/bar`, we can specify that path using `path = Some "foo/bar"` for the package entry.

### What about *multiple packages* in one `repo`?

The `path` field also permits multiple packages within one repository.

Suppose that `https://github.com/theUsername/theRepo` has two subdirectories, `apple` and `banana`, each with the source code for a `vessel` package.

We can specify these packages in our package set as follows:

```dhall
{
"name": "apple",
"repo": "https://github.com/theUsername/theRepo.git",
"path": Some "apple/src",
"version": "v1.1.1",
"dependencies": ["base", "banana"]
},
{
"name": "banana",
"repo": "https://github.com/theUsername/theRepo.git",
"path": Some "banana/src",
"version": "v2.2.2",
"dependencies": ["base"]
}
```

Notice that the field `path` appears in each entry, to direct `vessel` within the single, shared `repo`.

### How do I integrate `vessel` into my custom build?

Running `vessel sources` will return flags in a format you can pass directly to
Expand Down
32 changes: 26 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@ pub fn download_compiler(version: &str) -> Result<PathBuf> {
Ok(dest)
}

/// Downloads a package either as a tar-ball from Github or clones it as a repo
/// Downloads a package either as a tar-ball from Github or clones it as a repo.
/// Returns its installation location.
pub fn download_package(package: &Package) -> Result<PathBuf> {
let package_dir = Path::new(".vessel").join(package.name.clone());
if !package_dir.exists() {
Expand Down Expand Up @@ -294,7 +295,15 @@ pub fn download_package(package: &Package) -> Result<PathBuf> {
package.name, package.version
)
}
Ok(repo_dir.join("src"))
// include the package path within the repo, if it exists.
match package.path {
None => Ok(repo_dir.join("src")),
Some(ref p) => {
let q = Path::new(p);
assert!(q.is_relative()); // otherwise .join will misbehave
Ok(repo_dir.join(q))
}
}
}

/// Downloads and unpacks a tar-ball from Github into the `dest` path
Expand Down Expand Up @@ -370,7 +379,6 @@ fn clone_package(tmp: &Path, dest: &Path, repo: &str, version: &str) -> Result<(
std::str::from_utf8(&checkout_result.stderr).unwrap()
));
}

fs::rename(repo_dir, dest)?;
Ok(())
}
Expand Down Expand Up @@ -505,20 +513,31 @@ pub type Tag = String;

pub type Name = String;

pub type PackagePath = String;

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, serde_dhall::StaticType)]
pub struct Package {
pub name: Name,
pub repo: Url,
pub path: Option<PackagePath>,
pub version: Tag,
pub dependencies: Vec<Name>,
}

impl Package {
pub fn install_path(&self) -> PathBuf {
Path::new(".vessel")
let path = Path::new(".vessel")
.join(self.name.clone())
.join(self.version.clone())
.join("src")
.join(self.version.clone());
// include the package path within the repo, if it exists.
match self.path {
None => path.join("src"),
Some(ref p) => {
let q = Path::new(p);
assert!(q.is_relative()); // otherwise .join will misbehave
path.join(q)
}
}
}

/// Returns all Motoko sources found inside this package's installation directory
Expand Down Expand Up @@ -609,6 +628,7 @@ mod test {
Package {
name: name.to_string(),
repo: "".to_string(),
path: None,
version: "".to_string(),
dependencies: deps.into_iter().map(|x| x.to_string()).collect(),
}
Expand Down