Skip to content

Commit

Permalink
Add fileset helpers (ipetkov#731)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Ivan Petkov <ivanppetkov@gmail.com>
  • Loading branch information
2 people authored and ulucs committed Dec 3, 2024
1 parent 8f8e943 commit 308773e
Show file tree
Hide file tree
Showing 16 changed files with 210 additions and 45 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## Unreleased

### Added
* Added a number of fileset helpers to more easily compose source filtering:
* `fileset.cargoTomlAndLock`: for `Cargo.toml` and `Cargo.lock` files
* `fileset.commonCargoSources`: for files commonly used by cargo projects
* `fileset.configToml`: for `config.toml` files
* `fileset.rust`: for `*.rs` files
* `fileset.toml`: for `*.toml` files

### Fixed
* `buildTrunkPackage` will pass in `--release=true` (instead of just
`--release`) for trunk versions 0.21 or higher to avoid argument ambiguities
Expand Down
36 changes: 36 additions & 0 deletions checks/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,42 @@ in

features = callPackage ./features { };

fileset = myLib.buildPackage {
src = lib.fileset.toSource {
root = ./simple;
fileset = myLib.fileset.commonCargoSources ./simple;
};
};

filesetBuildScript = myLib.buildPackage {
src = lib.fileset.toSource {
root = ./with-build-script;
fileset = myLib.fileset.commonCargoSources ./with-build-script;
};
};

filesetWorkspace = myLib.buildPackage {
src = lib.fileset.toSource {
root = ./workspace;
fileset = myLib.fileset.commonCargoSources ./workspace;
};
};

filesetWorkspaceInheritance = myLib.buildPackage {
src = lib.fileset.toSource {
root = ./workspace-inheritance;
fileset = myLib.fileset.commonCargoSources ./workspace-inheritance;
};
};

filesetWorkspaceRoot = myLib.buildPackage {
src = lib.fileset.toSource {
root = ./workspace-root;
fileset = myLib.fileset.commonCargoSources ./workspace-root;
};
pname = "workspace-root";
};

gitOverlappingRepo = myLib.buildPackage {
src = ./git-overlapping;
};
Expand Down
44 changes: 43 additions & 1 deletion docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,6 @@ cleanSourceWith {
name = "source"; # Be reproducible, regardless of the directory name
}
```

Note that it is possible to compose source filters, especially if
`filterCargoSources` omits files which are relevant to the build. For example:

Expand All @@ -1094,6 +1093,47 @@ cleanSourceWith {
}
```

### `craneLib.fileset.cargoTomlAndLock`

`cargoTomlAndLock :: path -> fileset`

A [fileset] helper which will only include any `Cargo.toml` and `Cargo.lock`
files from the specified path.

### `craneLib.fileset.commonCargoSources`

`commonCargoSources :: path -> fileset`

A [fileset] helper which will only include any files commonly used by cargo
projects from the specified path. Essentially a union of:

* `craneLib.fileset.cargoTomlAndLock`
* `craneLib.fileset.rust`
* `craneLib.fileset.toml`

### `craneLib.fileset.configToml`

`configToml :: path -> fileset`

A [fileset] helper which will only include `config.toml` files from the
specified path.

Note that cargo usually only pays attention to `config.toml` files if they are
present inside of a directory named `.cargo`. This fileset will contain any
`config.toml` file, even if its parent directory is _not_ named `.cargo`.

### `craneLib.fileset.rust`

`rust :: path -> fileset`

A [fileset] helper which will only include `*.rs` files from the specified path.

### `craneLib.fileset.toml`

`toml :: path -> fileset`

A [fileset] helper which will only include `*.toml` files from the specified path.

### `craneLib.mkCargoDerivation`

`mkCargoDerivation :: set -> drv`
Expand Down Expand Up @@ -1866,3 +1906,5 @@ Defines `replaceCargoLock()` which handles replacing or inserting a specified
**Automatic behavior:** if `cargoLock` is set and
`doNotReplaceCargoLock` is not set, then `replaceCargoLock "$cargoLock"` will be
run as a pre patch hook.

[fileset]: https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-fileset
2 changes: 1 addition & 1 deletion docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* [Workspace with Trunk](./examples/trunk-workspace.md)
* [End-to-End Testing](./examples/end-to-end-testing.md)
* [Building with SQLx](./examples/sqlx.md)
* [Source filtering](./source-filtering.md)
* [Source filtering and filesets](./source-filtering.md)
* [Local development](./local_development.md)
* [Custom cargo commands](./custom_cargo_commands.md)
* [Customizing builds](./customizing_builds.md)
Expand Down
27 changes: 27 additions & 0 deletions docs/source-filtering.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,30 @@ craneLib.buildPackage {
};
}
```

## Fileset filtering

A more composable alternative to source filtering is using [filesets]:

```nix
let
unfilteredRoot = ./.; # The original, unfiltered source
src = lib.fileset.toSource {
root = unfilteredRoot;
fileset = lib.fileset.unions [
# Default files from crane (Rust and cargo files)
(craneLib.fileset.commonCargoSources unfilteredRoot)
# Also keep any markdown files
(lib.fileset.fileFilter (file: file.hasExt == "md") unfilteredRoot)
# Example of a folder for images, icons, etc
(lib.fileset.maybeMissing ./assets)
];
};
in
craneLib.buildPackage {
# other attributes omitted
inherit src;
}
```

[filesets]: https://nixos.org/manual/nixpkgs/unstable/#sec-functions-library-fileset
6 changes: 3 additions & 3 deletions examples/quick-start-workspace/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@
fileset = lib.fileset.unions [
./Cargo.toml
./Cargo.lock
./crates/my-common
./crates/my-workspace-hack
crate
(craneLib.fileset.commonCargoSources ./crates/my-common)
(craneLib.fileset.commonCargoSources ./crates/my-workspace-hack)
(craneLib.fileset.commonCargoSources crate)
];
};

Expand Down
16 changes: 9 additions & 7 deletions examples/sqlx/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@

craneLib = crane.mkLib pkgs;

sqlFilter = path: _type: null != builtins.match ".*sql$" path;
sqlOrCargo = path: type: (sqlFilter path type) || (craneLib.filterCargoSources path type);

src = lib.cleanSourceWith {
src = ./.; # The original, unfiltered source
filter = sqlOrCargo;
name = "source"; # Be reproducible, regardless of the directory name
unfilteredRoot = ./.; # The original, unfiltered source
src = lib.fileset.toSource {
root = unfilteredRoot;
fileset = lib.fileset.unions [
# Default files from crane (Rust and cargo files)
(craneLib.fileset.commonCargoSources unfilteredRoot)
# Include all the .sql migrations as well
./migrations
];
};

# Common arguments can be set here to avoid repeating them later
Expand Down
22 changes: 12 additions & 10 deletions examples/trunk-workspace/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,21 @@
});

# When filtering sources, we want to allow assets other than .rs files
src = lib.cleanSourceWith {
src = ./.; # The original, unfiltered source
filter = path: type:
(lib.hasSuffix "\.html" path) ||
(lib.hasSuffix "\.scss" path) ||
unfilteredRoot = ./.; # The original, unfiltered source
src = lib.fileset.toSource {
root = unfilteredRoot;
fileset = lib.fileset.unions [
# Default files from crane (Rust and cargo files)
(craneLib.fileset.commonCargoSources unfilteredRoot)
(lib.fileset.fileFilter
(file: lib.any file.hasExt [ "html" "scss" ])
unfilteredRoot
)
# Example of a folder for images, icons, etc
(lib.hasInfix "/assets/" path) ||
# Default filter from crane (allow .rs files)
(craneLib.filterCargoSources path type)
;
(lib.fileset.maybeMissing ./assets)
];
};


# Arguments to be used by both the client and the server
# When building a workspace with crane, it's a good idea
# to set "pname" and "version".
Expand Down
21 changes: 12 additions & 9 deletions examples/trunk/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,19 @@
});

# When filtering sources, we want to allow assets other than .rs files
src = lib.cleanSourceWith {
src = ./.; # The original, unfiltered source
filter = path: type:
(lib.hasSuffix "\.html" path) ||
(lib.hasSuffix "\.scss" path) ||
unfilteredRoot = ./.; # The original, unfiltered source
src = lib.fileset.toSource {
root = unfilteredRoot;
fileset = lib.fileset.unions [
# Default files from crane (Rust and cargo files)
(craneLib.fileset.commonCargoSources unfilteredRoot)
(lib.fileset.fileFilter
(file: lib.any file.hasExt [ "html" "scss" ])
unfilteredRoot
)
# Example of a folder for images, icons, etc
(lib.hasInfix "/assets/" path) ||
# Default filter from crane (allow .rs files)
(craneLib.filterCargoSources path type)
;
(lib.fileset.maybeMissing ./assets)
];
};

# Common arguments can be set here to avoid repeating them later
Expand Down
9 changes: 9 additions & 0 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ let
downloadCargoPackageFromGit = callPackage ./downloadCargoPackageFromGit.nix { };
downloadCargoRegistry = callPackage ./downloadCargoRegistry.nix { };
filterCargoSources = callPackage ./filterCargoSources.nix { };

fileset = {
cargoTomlAndLock = callPackage ./fileset/cargoTomlAndLock.nix { };
commonCargoSources = callPackage ./fileset/commonCargoSources.nix { };
configToml = callPackage ./fileset/configToml.nix { };
rust = callPackage ./fileset/rust.nix { };
toml = callPackage ./fileset/toml.nix { };
};

findCargoFiles = callPackage ./findCargoFiles.nix { };
inheritCargoArtifactsHook = callPackage ./setupHooks/inheritCargoArtifacts.nix { };
installCargoArtifactsHook = callPackage ./setupHooks/installCargoArtifacts.nix { };
Expand Down
7 changes: 7 additions & 0 deletions lib/fileset/cargoTomlAndLock.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{ lib
}:

path:
lib.fileset.fileFilter
(file: lib.elem file.name [ "Cargo.toml" "Cargo.lock" ])
path
12 changes: 12 additions & 0 deletions lib/fileset/commonCargoSources.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{ fileset
, lib
}:

path:
lib.fileset.unions [
(fileset.cargoTomlAndLock path)
(fileset.rust path)
# Keep all toml files as they are commonly used to configure other
# cargo-based tools
(fileset.toml path)
]
9 changes: 9 additions & 0 deletions lib/fileset/configToml.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{ lib
}:

path:
lib.fileset.fileFilter
# Technically this should be scoped to `.cargo/config.toml` but (currently)
# there is no way to do this with file sets in a generic manner
(file: file.name == "config.toml")
path
7 changes: 7 additions & 0 deletions lib/fileset/rust.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{ lib
}:

path:
lib.fileset.fileFilter
(file: file.hasExt "rs")
path
7 changes: 7 additions & 0 deletions lib/fileset/toml.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{ lib
}:

path:
lib.fileset.fileFilter
(file: file.hasExt "toml")
path
22 changes: 8 additions & 14 deletions pkgs/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@
book =
let
inherit (pkgs) lib;
root = myLib.path ./..;
rootPrefix = toString root;
cleanedSrc = lib.cleanSourceWith {
src = root;
filter = path: _:
let
relativePath = lib.removePrefix rootPrefix path;
in
lib.any (prefix: lib.hasPrefix prefix relativePath) [
"/docs" # Build the docs directory
"/examples" # But also include examples as we cross-reference them
"/README.md"
"/CHANGELOG.md"
];
cleanedSrc = lib.fileset.toSource {
root = ./..;
fileset = lib.fileset.unions [
./../docs
./../examples
./../README.md
./../CHANGELOG.md
];
};
in
pkgs.runCommand "crane-book" { } ''
Expand Down

0 comments on commit 308773e

Please sign in to comment.