-
Notifications
You must be signed in to change notification settings - Fork 620
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
path: Make os an option argument #687
Comments
I can take a look at this later if no one else is working on it 👍🏼 I can see 2 ways to do it though, not sure which one is best: 1. Creating a new single file which abstract each function with the additional os option //paths.ts
import * as _win32 from "./win32.ts";
import * as _posix from "./posix.ts";
export function basename(..., {os = Deno.build.os}:{os?:typeof Deno.build.os}) {
return (os === "windows") ? _win32.basename(...arguments) : posix.basename(...arguments)
} And we 2. Splitting win32.ts and posix.ts and reorder each function into a single file (like for test files) //basename.ts
export function basename(..., {os = Deno.build.os}:{os?:typeof Deno.build.os}) {
return (os === "windows") ? win32Basename(...arguments) : posixBasename(...arguments)
}
function _win32Basename(...) { /* old basename function from win32.ts */ }
function _posixBasename(...) { /* old basename function from posix.ts */ }
//other files for each path function which has a named file test This breaks retro-compatibility with people importing directly from |
@lowlighter are you still interested in working on this? |
@bartlomieju I can work on it, just need to know which approach I should take Personally I'm more for the 2nd one to be consistent with other std sections, but it breaks retro-compatibility. Or else I guess I could turn |
I don't have a strong opinion regarding this, @nayeemrmn what do you think? |
Assuming breakages are okay, my vision was just removing // mod.ts
export * from "./common.ts";
export * from "./glob.ts";
export * from "./separator.ts";
export function basename(..., {os = Deno.build.os}:{os?:typeof Deno.build.os}) {
if (Deno.build.os == "windows") {
// windows implementation...
} else {
// unix implementation...
}
}
export function dirname(..., {os = Deno.build.os}:{os?:typeof Deno.build.os}) {
if (Deno.build.os == "windows") {
// windows implementation...
} else {
// unix implementation...
}
} The reason I don't want to split the modules up front (even though that's one of the justifications of this design) is that the structure of those files could be in question whereas this is a forward-compatible option that could be pushed through slightly faster. Plus, I'm still interested in renaming the functions based on Rust stdlib and the file names would be based on those. |
@nayeemrmn Ok so basically it's just merging Shoving them all in |
Having |
Seems that they are already tests files splitted for each function ( Also I noticed that some functions are actually quite similar, should I merge their implementations to minimize code ? |
I'll open a PR tomorrow to tackle this. This needs to be done before 1.0 imo. |
We need to discuss requirements for
These questions can only really be answered with concrete, supported use cases imo. I'm not really sure how to go about answering these. |
I think that (generally for all of Re: rest params vs a single iterable argument: I think there's going to be a tradeoff in ergonomics depending on usage patterns. In the examples below, I expect the second API to cause more developer surprises since they need to provide their own iterable container for a single argument: // Example: Getting an absolute path from a relative one
// Current API: accepts rest params
path.resolve("relative_file.ext"); // "/Users/deno/relative_file.ext" // API under discussion: accepts a single iterable param
// Intended usage:
path.resolve(["relative_file.ext"]); // "/Users/deno/relative_file.ext"
// ⚠️ Not a type error, but will iterate UTF-16 substrings,
// which is almost certainly not what the developer intended,
// and a potentially very difficult to catch bug:
path.resolve("relative_file.ext"); // "/Users/deno/r/e/l/a/t/i/v/e/_/f/i/l/e/./e/x/t" If developer usage indicates that consumers are overwhelmingly likely to already have and use their own iterables, then the single-argument API would be more ergonomic than the current rest parameter API. |
From the initial post:
I am surprised to see this comment, especially this part:
IMO it's important to quantify (or at least qualify) descriptions like "niche" when considering addition or removal of APIs. From my view,
When I'm solving niche problems or implementing a new library, I find the category 1 parts to be indispensable. However, I find value much more often in the category 2 utilities (such as the ability to manipulate paths for a platform other than the one I'm currently using to run the code.) |
The use case I meant is the ability to pass around a |
@lino-levan I agree. Closing Note: We didn't implement this (especially |
The export structure of the
path
module looks like this:This seems archaic and overly bound to where we vendored the implementation. It forces us to put group every function by OS in just
path/posix.ts
andpath/win32.ts
, rather than having modules likepath/join.ts
,path/file_url.ts
, etc. It's hard to maintain and the test modules don't match it.We should instead export one set of functions which each have an options interface containing the OS. They all have few enough positional arguments. This is modelled already by
path/glob.ts
, which gets to have its own module, containing:These functions can branch by OS individually.
The current structure allows importing one namespace of functions for another OS, but this is niche enough that users should make such an abstraction themselves if they need it (in reality they can just import it from the
node/
polyfill).Ref https://github.com/denoland/deno/discussions/8405.
The text was updated successfully, but these errors were encountered: