Skip to content

Commit

Permalink
feat: Path - add linkTo and linkToSync (#268)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret authored May 4, 2024
1 parent c9eb52f commit 3b78fdf
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 6 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ pb.with(() => {

## Path API

The path API offers an immutable [`Path`](https://deno.land/x/dax/src/path.ts?s=Path) class, which is a similar concept to Rust's `PathBuf` struct.
The path API offers an immutable [`Path`](https://jsr.io/@david/dax/doc/~/Path) class, which is a similar concept to Rust's `PathBuf` struct.

```ts
// create a `Path`
Expand Down Expand Up @@ -659,7 +659,7 @@ const pathStringFileUrl = $.path("file:///tmp"); // converts to /tmp
const pathImportMeta = $.path(import.meta); // the path for the current module
```

There are a lot of helper methods here, so check the [documentation on Path](https://deno.land/x/dax/src/path.ts?s=Path) for more details.
There are a lot of helper methods here, so check the [documentation on Path](https://jsr.io/@david/dax/doc/~/Path) for more details.

## Helper functions

Expand Down Expand Up @@ -771,7 +771,7 @@ await $`deno run main.ts`.stdin(request);
await $`sleep 5 && deno run main.ts < ${request}`;
```

See the [documentation on `RequestBuilder`](https://deno.land/x/dax/src/request.ts?s=RequestBuilder) for more details. It should be as flexible as `fetch`, but uses a builder API (ex. set headers via `.header(...)`).
See the [documentation on `RequestBuilder`](https://jsr.io/@david/dax/doc/~/RequestBuilder) for more details. It should be as flexible as `fetch`, but uses a builder API (ex. set headers via `.header(...)`).

### Showing progress

Expand Down Expand Up @@ -907,7 +907,7 @@ The builder APIs are what the library uses internally and they're useful for sce
`CommandBuilder` can be used for building up commands similar to what the tagged template `$` does:

```ts
import { CommandBuilder } from "https://deno.land/x/dax/mod.ts";
import { CommandBuilder } from "@david/dax";

const commandBuilder = new CommandBuilder()
.cwd("./subDir")
Expand Down Expand Up @@ -948,7 +948,7 @@ const result = await commandBuilder
`RequestBuilder` can be used for building up requests similar to `$.request`:

```ts
import { RequestBuilder } from "https://deno.land/x/dax/mod.ts";
import { RequestBuilder } from "@david/dax";

const requestBuilder = new RequestBuilder()
.header("SOME_VALUE", "some value to send in a header");
Expand All @@ -964,7 +964,7 @@ const result = await requestBuilder
You may wish to create your own `$` function that has a certain setup context (for example, custom commands or functions on `$`, a defined environment variable or cwd). You may do this by using the exported `build$` with `CommandBuilder` and/or `RequestBuilder`, which is essentially what the main default exported `$` uses internally to build itself. In addition, you may also add your own functions to `$`:

```ts
import { build$, CommandBuilder, RequestBuilder } from "https://deno.land/x/dax/mod.ts";
import { build$, CommandBuilder, RequestBuilder } from "@david/dax";

// creates a $ object with the provided starting environment
const $ = build$({
Expand Down
24 changes: 24 additions & 0 deletions src/path.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,30 @@ Deno.test("symlinkToSync", async () => {
});
});

Deno.test("linkTo", async () => {
await withTempDir(async () => {
const destFile = createPath("temp.txt").writeTextSync("data");

// async
{
const hardlinkFile = destFile.parentOrThrow().join("other.txt");
await hardlinkFile.linkTo(destFile);
const stat = hardlinkFile.statSync();
assertEquals(stat!.isFile, true);
assertEquals(stat!.isSymlink, false);
assert(!hardlinkFile.isSymlinkSync());
assertEquals(hardlinkFile.readTextSync(), "data");
}

// sync
{
const hardlinkFile = destFile.parentOrThrow().join("sync.txt");
hardlinkFile.linkToSync(destFile);
assertEquals(hardlinkFile.readTextSync(), "data");
}
});
});

Deno.test("readDir", async () => {
await withTempDir(async () => {
const dir = createPath(".").resolve();
Expand Down
20 changes: 20 additions & 0 deletions src/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,26 @@ export class Path {
}
}

/**
* Creates a hardlink to the provided target path.
*/
async linkTo(
targetPath: string | URL | Path,
): Promise<void> {
const targetPathRef = ensurePath(targetPath).resolve();
await Deno.link(targetPathRef.toString(), this.resolve().toString());
}

/**
* Synchronously creates a hardlink to the provided target path.
*/
linkToSync(
targetPath: string | URL | Path,
): void {
const targetPathRef = ensurePath(targetPath).resolve();
Deno.linkSync(targetPathRef.toString(), this.resolve().toString());
}

/** Reads the entries in the directory. */
async *readDir(): AsyncIterable<WalkEntry> {
const dir = this.resolve();
Expand Down

0 comments on commit 3b78fdf

Please sign in to comment.