Giter VIP home page Giter VIP logo

path's Introduction

Dart CI pub package package publisher

A comprehensive, cross-platform path manipulation library for Dart.

The path package provides common operations for manipulating paths: joining, splitting, normalizing, etc.

We've tried very hard to make this library do the "right" thing on whatever platform you run it on, including in the browser. When you use the top-level functions, it will assume the current platform's path style and work with that. If you want to explicitly work with paths of a specific style, you can construct a p.Context for that style.

Using

The path library was designed to be imported with a prefix, though you don't have to if you don't want to:

import 'package:path/path.dart' as p;

The most common way to use the library is through the top-level functions. These manipulate path strings based on your current working directory and the path style (POSIX, Windows, or URLs) of the host platform. For example:

p.join('directory', 'file.txt');

This calls the top-level join() function to join the "directory" and "file.txt" using the current platform's directory separator.

If you want to work with paths for a specific platform regardless of the underlying platform that the program is running on, you can create a Context and give it an explicit [Style]:

var context = p.Context(style: Style.windows);
context.join('directory', 'file.txt');

This will join "directory" and "file.txt" using the Windows path separator, even when the program is run on a POSIX machine.

Stability

The path package is used by many Dart packages, and as such it strives for a very high degree of stability. For the same reason, though, releasing a new major version would probably cause a lot of versioning pain, so some flexibility is necessary.

We try to guarantee that operations with valid inputs and correct output will not change. Operations, where one or more inputs are invalid according to the semantics of the corresponding platform, may produce different outputs over time. Operations for which path produces incorrect output will also change so that we can fix bugs.

Also, the path package's URL handling is based on the WHATWG URL spec. This is a living standard, and some parts of it haven't yet been entirely solidified by vendor support. The path package reserves the right to change its URL behavior if the underlying specification changes, although if the change is big enough to break many valid uses we may elect to treat it as a breaking change anyway.

FAQ

Where can I use this?

The path package runs on the Dart VM and in the browser under both dart2js and Dartium. On the browser, window.location.href is used as the current path.

Why doesn't this make paths first-class objects?

When you have path objects, then every API that takes a path has to decide if it accepts strings, path objects, or both.

  • Accepting strings is the most convenient, but then it seems weird to have these path objects that aren't actually accepted by anything that needs a path. Once you've created a path, you have to always call .toString() on it before you can do anything useful with it.

  • Requiring objects forces users to wrap path strings in these objects, which is tedious. It also means coupling that API to whatever library defines this path class. If there are multiple "path" libraries that each define their own path types, then any library that works with paths has to pick which one it uses.

  • Taking both means you can't type your API. That defeats the purpose of having a path type: why have a type if your APIs can't annotate that they expect it?

Given that, we've decided this library should simply treat paths as strings.

How cross-platform is this?

We believe this library handles most of the corner cases of Windows paths (POSIX paths are generally pretty straightforward):

  • It understands that both "/" and "\" are valid path separators, not just "\".

  • It can accurately tell if a path is absolute based on drive-letters or UNC prefix.

  • It understands that "/foo" is not an absolute path on Windows.

  • It knows that "C:\foo\one.txt" and "c:/foo\two.txt" are two files in the same directory.

What is a "path" in the browser?

If you use this package in a browser, then it considers the "platform" to be the browser itself and uses URL strings to represent "browser paths".

path's People

Contributors

ayan-b avatar bcko avatar chalin avatar dantup avatar dependabot[bot] avatar devoncarew avatar dgrove avatar efortuna avatar floitschg avatar franklinyow avatar hellohuanlin avatar jakemac53 avatar jcollins-g avatar jensjoha avatar kevmoo avatar lexaknyazev avatar lrhn avatar mihiron avatar munificent avatar natebosch avatar nex3 avatar peter-ahe-google avatar saintgabriel0 avatar srawlins avatar szakarias avatar theultimateoptimist avatar vsmenon avatar whesse avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

path's Issues

does not parse ~

unix users are used to ~ as the home directory of the user and to reference paths from there
standard dart.io is not able to cope with ~, since path is able to make absolute paths out of relative ones, it would be nice if it could cope with ~....

ATM i do:

    fname = fname.replaceFirst('~', Platform.environment['HOME'].toString());
    fname = path.canonicalize(fname);

but that extra step seems silly and IMHO should be included in the lib?

Remove the optional arguments to absolute`()

The absolute() function supports six optional arguments, in the same manner as join(). These arguments are rarely used in practice, and are an odd divergence from path's usual style of functions that do a single job. They also presumably add a small amount of overhead in the very common case of making a single path absolute. Once we decide to make a release with breaking changes, it should remove these arguments.

Delete deprecated public style properties

The Style class has a number of deprecated public APIs that are a vestige of an ill-fated attempt to allow user-defined path styles. These should be deleted when we decided to put out a breaking release.

UnimplementedError: Uri.base on a background isolate is not supported in the browser

In the context of a web worker Uri.base is not defined.

UnimplementedError: Uri.base on a background isolate is not supported in the browser
[From isolate] #0      _pureIsolateUriBaseClosure.<anonymous closure> (dart:html:42206)
#1      Uri.base (dart:core-patch/uri_patch.dart:21)
#2      Style._getPlatformStyle (package:path/src/style.dart:45:13)
#3      Style.platform (package:path/src/style.dart:37:44)
#4      Style.platform (package:path/src/style.dart:37:16)
#5      Context.Context._internal (package:path/src/context.dart:47:39)
#6      createInternal (package:path/src/context.dart:13:33)
#7      context (package:path/path.dart:70:39)
#8      context (package:path/path.dart:70:15)
#9      prettyUri (package:path/path.dart:381:26)
#10     Frame.library (package:stack_trace/src/frame.dart:82:39)
#11     Trace.terse.<anonymous closure> (package:stack_trace/src/trace.dart:220:27)
#12     MappedListIterable.elementAt (dart:_internal/iterable.dart:413)
#13     ListIterable.toList (dart:_internal/iterable.dart:219)
#14     Trace.Trace (package:stack_trace/src/trace.dart:200:63)
#15     Trace.terse (package:stack_trace/src/trace.dart:216:16)
#16     LazyTrace.terse.<anonymous closure> (package:stack_trace/src/lazy_trace.dart:29:49)
#17     LazyTrace._trace (package:stack_trace/src/lazy_trace.dart:23:40)
#18     LazyTrace.frames (package:stack_trace/src/lazy_trace.dart:27:29)
#19     Chain.terse.<anonymous closure> (package:stack_trace/src/chain.dart:178:20)
#20     WhereIterator.moveNext (dart:_internal/iterable.dart:436)
#21     IterableBase.isEmpty (dart:collection/iterable.dart:298)
#22     Chain.terse (package:stack_trace/src/chain.dart:183:24)
#23     _getErrorMessage (package:shelf/src/handlers/logger.dart:64:74)
#24     logRequests.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:shelf/src/handlers/logger.dart:43:33)
#25     _RootZone.runBinary (dart:async/zone.dart:1160)
#26     _Future._propagateToListeners.handleError (dart:async/future_impl.dart:511)
#27     _Future._propagateToListeners (dart:async/future_impl.dart:570)
#28     _Future._completeError (dart:async/future_impl.dart:366)
#29     _Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:421)
#30     _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#31     _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#32     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96)
#33     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:143)

extension() long name

I hit a bug with extension(), it only happen in Angular (Web) projects, this may be related to dart2js :

To reproduce create a stagehand angular project, add path: ^1.6.2 and following code in main.dart :

import 'package:angular/angular.dart';
import 'package:buga/app_component.template.dart' as ng;
import 'package:path/path.dart' as path;

void main() {
  print("EXT : " + path.extension("Xxx: Xxxxxxx xx x'xxxxx xxxxxxxxxx XXXXXX xxxxxxxx xx xxxxxx xxxxxxxxxx xxxxx x° xxx xxx xxx, xxxxxxxx xxxxxx xxx xxxxxxxxxx xxxxxx xxxxx x° xxx xxx xxx xx xxxxxx xxxxxxx xx xxxxxx xxxxxxxxxx xxxxx x° xxx xxx xxx.eml"));
  runApp(ng.AppComponentNgFactory);
}

will output an empty extension (expected result is .eml):

EXT : 

Not that in a console application this works as expexed

$ dart --version
Dart VM version: 2.3.0 (Unknown timestamp) on "linux_x64"

relative() and isWithin() are not case insensitive on Windows

This:

import 'package:path/path.dart' as p;

main() {
  print(p.windows.isWithin(r"a\b", r"a\B\c"));
  print(p.windows.isWithin(r"a:b\c", r"A:\b\c\d"));
  print(p.windows.relative(r"a:\b\c\d", from: r"a:\B\c"));
  print(p.windows.relative(r"a:\b\c\d", from: r"A:\b\c"));
}

Prints:

false
false
..\..\b\c\d
d

The first three are wrong. Interestingly, the last is right!

So isWithin() is not handling case sensitivity of drive letters or paths. relative() is handling drive letters, but not paths.

canonicalize on MacOS is broken

canonicalize promises to "return the same path for two different input paths if and only if both input paths point to the same location" [1]. On Mac OS with its case insensitive file system this is not true: TEST.dart and test.dart reference the same file on Mac OS. However, canonicalize("TEST.dart") is not equal to canonicalize("test.dart"):

print(canonicalize("TEST.dart"));  // this prints "TEST.dart"
print(canonicalize("test.dart"));   // this prints "test.dart"

[1] https://www.dartdocs.org/documentation/path/1.4.1/path/canonicalize.html

please support package's protocol path

classMirror.location.sourceUrl is a package'protocol path, such as package:path/src/context.dart, please support get it's dir like package:path/src, and support join

Provide clearer documenation on use age of / as root

The documentation doesn't provide clear guidance on how you stipulate a root path in a cross platform manner.
Whist \tmp isn't an absolute path on windows it does describe a path that is relative to the root directory of the current drive and below I will refer to this as an root relative path.

Reading the documentation its not clear how to stipulate a root relative path.

For instance are each of the following the same:

join('/tmp');
join('/', 'tmp');
join('\tmp');
join('', 'tmp');

It would be useful if the documentation was explicit on this point.

Add support for Zones to assist with unit testing.

I'm the author of dshell

https://pub.dev/packages/dshell.

I'm using the path package extensively.

I'm currently trying to write unit tests for dshell and having some problems.

Dshell creates a ~/.dshell directory and all my unit tests make adjustments to this directory and its children.

When running unit tests this can be problematic for two reasons.

  1. unit tests can't be serialized so different unit tests are writing over each others changes to ~/.dshell and its children
  2. Modifying my local file system is of concern as a number of my unit tests do recursive deletes.

As such I'm trying to use Zones and the MemoryFileSystem.
This seems like it will work however the path package causes problems.

The path package has a number of global variables. The key pain point is the 'current' variable that maintains a cache of of the current working directory.

As this variable is global it is shared across zones which means that my unit tests still interfere with each other (e.g. if one test changes the CWD then all unit tests get the new CWD).

It seems to me that we could modify the paths package to be zone aware without much effort.

The 'current' method could be modified to check if it is in the root zone via;
Zone.current == Zone.root

If it is in the root zone it continues as it currently does.
If its not in the root zone then we could modified to pull its settings from a Zone key.

_current = Zone[#paths]._current;

The #paths key would be a unique class that contains all of the global settings that paths uses.

If I submitted a change to make the path package zone aware would it be accepted (assuming suitable quality standards are met)?

I believe these changes could be made without modifying the current api.

setExtension removes part of a filename if it contained dot

I'm composing a path to a file. The name of this file does not have extension, but it contains a dot (e.g. "fullPath/abc.xyz"). When I try to set the extension for this file (e.g. "txt"), I get not what I expect: "fullPath/abc.txt".

Looking at this code, I understand how it happens.

  String setExtension(String path, String extension) =>
      withoutExtension(path) + extension;

It looks like a naming problem for me. I have no option so set the extension for the file without extension.
What do you think?

add "__filename" and "__dirname"

I want to get the script path in a simpler way:

import 'dart:io';
import 'package:path/path.dart' as path;

final String __filename = Platform.script.path.replaceFirst('/', '');
final String __dirname = path.dirname(__filename);

main(List<String> args) async {
  print('path.current: ${path.current}');
  print('__filename: $__filename');
  print('__dirname: $__dirname');
}

run:

ajanuw@ajanuw /d/ajanuw/dart-test
λ dart bin/main.dart
path.current: D:\ajanuw\dart-test
__filename: D:/ajanuw/dart-test/bin/main.dart
__dirname: D:/ajanuw/dart-test/bin

Windows paths shouldn't be canonicalized to lower-case

Although most paths on Windows are case-insensitive, it's possible to set certain directories as case-sensitive. This means that canonicalize() as currently implemented—converting all Windows paths to lower case—can cause a valid path to become invalid. It should probably instead match the behavior of other filesystems (including Mac OS which is also sometimes case-sensitive) and leave the case as-is.

Note that this means that, in general, paths cannot be truly canonicalized (in the sense of "guaranteeing that two paths that refer to the same location on disk will have the same string") without actually interacting with the filesystem on Windows (or Mac OS). This should probably be called out in the documentation.

Path and Dart SDK disagree about Windows behavior of absolute file URIs without drive names

The following script illustrates the problem:

import 'package:path/path.dart' as path;

void check(Uri uri) {
  print('For uri: $uri');
  print('  uri.toFilePath(windows: true) => "${uri.toFilePath(windows: true)}"');
  print('  path.windows.fromUri(uri) => "${path.windows.fromUri(uri)}"');
}

main() {
  check(Uri.parse('file:///foo'));
  check(Uri.parse('/foo'));
}

This produces the following output:

For uri: file:///foo
  uri.toFilePath(windows: true) => "\foo"
  path.windows.fromUri(uri) => "foo"
For uri: /foo
  uri.toFilePath(windows: true) => "\foo"
  path.windows.fromUri(uri) => "foo"

I realize that these file URIs aren't especially Windows-like, but it would be nice if the SDK and the path package treated them in the same way. I tend to favor the behavior of uri.toFilePath(windows: true), because at least it produces something that doesn't look like a relative path.

This bug is at the root of a unit test failure in analyzer--see dart-lang/sdk#27870.

Would like a better mechanism to match directory components

I've seen a fair amount of code that attempts to match path components using naive string operations. For example:

import 'package:path' as path;

/// Returns true if `absPath` is within `absParentPath`.
/// 
/// A path is considered to be "within" itself.  That is, returns
/// true if `absPath` and `absParentPath` are equal.
///
/// `absParentPath` and `absPath` must be absolute paths and normalized
/// (i.e. no trailing directory separators and no `.` nor `..` directory
/// components).
bool isWithinDirectory(String absParentPath, String absPath) {
  assert(path.isAbsolute(absParentPath));
  assert(path.isAbsolute(absPath));
  return absPath.startsWith(absParentPath); // Don't do this.
}

The above code works for most cases but is subtly wrong for isWithinDirectory('/foo/bar', '/foo/barstool'). A slightly less naive attempted fix:

  return absPath.startsWith(absParentPath + path.separator); // Don't do this either.

But now it's wrong for isWithinDirectory('/foo/bar', '/foo/bar'). So we need to do:

  return (absPath + path.separator).startsWith(absParentPath + path.separator);

I think that's now finally correct, but it's gross and unintuitive. Doing the right thing shouldn't be so hard. =(

It'd be nice if there were:

  1. A nicer way to ensure that paths have exactly one trailing directory separator. In Python this is easy: os.path.join(somePath, ""). Alas, join from package:path will not add a trailing separator if given empty strings, and changing that behavior probably would be scary, so it'd likely have to be done by some separate ensureTrailingSeparator or normalizeDirectory function. (Personally I think that normalizing directories to always have a trailing separator is less error-prone and has fewer corner cases (e.g. / or C:\).)

  2. A nicer way to match path subcomponents where matches that involve partial directory names are not considered.

(Better yet would be an abstraction around path components with conversions to/from String, and that would discourage string manipulations, enforce normalized paths, and provide type-safety..)

join() return a illegal path

the join return illegal path both on windows & linux

example

import 'package:path/path.dart' as path;

void main() {
  print(path.join('/root', './bilibili.png'));
}

Linux

expection: /root/bilibili.png
actuality: /root/./bilibili.png

Windows

expection: \root\bilibili.png
actuality: /root\./bilibili.png

Don't dynamically update the current working directory by default

Currently in the default context, operations that need to know the current working directory (current, relative(), isWithin(), absolute(), and prettyUri()) have to check the working directory every time they run. This involves a call to Uri.base, which is reasonably expensive on the command-line VM and puts a severe limit on how much these functions can be optimized.

On the other hand, it's not clear how much value this behavior adds. It's rare for an application to switch its working directory, and if it does all its existing in-memory relative paths will become invalid anyway. When we decide to put out a breaking release, we should make the default context cache the first known value of current. We can then provide a dynamic context that has the current dynamic-updating behavior for users who need it.

[Question] Is it possible to enforce style or context?

Hi!

I would like to know if it is possible to enforce style or context for path manipulation in particular scopes.

For my use case, I would like to use posix separator (/) even on Windows.

I tried the following:

final myPath = p.Style.posix.context.normalize(
  p.join(
    'this',
    'is',
    'my',
    'path',
  ),
);

print(myPath);

I also tried the following:

final myPath = p.posix.normalize(
  p.join(
    'this',
    'is',
    'my',
    'path',
  ),
);

print(myPath);

But the following is printed on Windows:

this\is\my\path

My expected output is:

this/is/my/path

Thanks in advance! 😄

importing error

I couldn't able to import it to my flutter project. I tried every versions but it seems I can't add it to my packages folder

Segments that are just a drive letter are dropped on Windows

On Windows, the following code:

final String homeDrive = platform.environment['HOMEDRIVE'];
final String homePath = platform.environment['HOMEPATH'];

print(homeDrive);
print(homePath);
print(fs.path.join(homeDrive, homePath));

Outputs the following:

C:
\Users\danny
\Users\danny

The value of HOMEDRIVE is something that's provided by Windows (without a trailing slash) and is often joined with HOMEPATH so maybe it makes sense to support it here.

normalize(null) behaviour should be defined

Currently, if you pass ``null` to normalize(), the function call fails with a cryptic error:

Unhandled exception:
The null object does not have a getter 'isNotEmpty'.

NoSuchMethodError: method not found: 'isNotEmpty'
Receiver: null
Arguments: []
#0      Object._noSuchMethod (dart:core-patch/object_patch.dart:42)
#1      Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
#2      PosixStyle.rootLength (package:path/src/style/posix.dart:34:14)
#3      InternalStyle.getRoot (package:path/src/internal_style.dart:46:18)
#4      ParsedPath.ParsedPath.parse (package:path/src/parsed_path.dart:45:22)
#5      Context._parse (package:path/src/context.dart:534:41)
#6      Context.normalize (package:path/src/context.dart:289:18)
#7      normalize (package:path/path.dart:271:42)

Either it should:

  • return null for a null input
  • throw a helpful error, e.g "null not allowed"

Thoughts? Which is more consistent with the package's style?

Bug in package "path" in Windows implementation

<img src="https://avatars.githubusercontent.com/u/2311549?v=3" align="left" width="96" height="96"hspace="10"> Issue by mezoni
Originally opened as dart-lang/sdk#18492


==== OK =====
pattern: "c:"
root: "c:"
segs: 1

==== OK =====
pattern: "c:&quot;
root: "c:"
segs: 1

==== OK =====
pattern: ""
root: ""
segs: 1

==== BAD =====
pattern: "&quot;
root: ""
segs: 0

As for me, "&quot; and all other similar (eg. "&quot;) should be reduced in favor of single "".
And this single "" should be considered as "root".

Currently pattern [sep][sep]+ matched in Windows not as in Posix.
I don't think that this path "&quot; in Windows relative.

Add p.changeExtension

This is especially common when writing compilers/transformers/tools.

Today we write:

String changeExtension(String path, String newExtension) {
  return '${withoutExtension(path)}$newExtension';
}

relative() returns incorrect result

We're seeing a failure in flutter's tests (flutter/flutter#1709) which looks like a bug in path's relative() function:

from: /var/folders/00/0w978000h01000cxqpysvccm003j4x/T/flutter_toolsZUIVMq
to:   /Users/devoncarew/projects/flutter/flutter/packages

result = path.relative(to, from: from);

result: ../../../../../../Users/devoncarew/projects/flutter/flutter/packages

The relative result isn't correct. It's off by one in the number of times it should traverse up to the parent directory. From flutter_toolsZUIVMq it can only go up 5 times to /, but it has 6 ..'s in the relative result.

package website unreachable

My application is stuck at pub get for a while
when i tried to check the problem behind it using -v
it was stuck at path and it returned this after a while

[        ] IO  : HTTP GET https://pub.dartlang.org/api/packages/path
[        ]     | Accept: application/vnd.pub.v2+json
[        ]     | X-Pub-OS: linux
[        ]     | X-Pub-Command: get
[        ]     | X-Pub-Session-ID: F7E23AB3-85C7-40B0-9161-ECF8B318AE40
[        ]     | X-Pub-Environment: flutter_bot:flutter_cli:verify:web
[        ]     | user-agent: Dart pub 2.10.4
[+129768 ms] IO  : HTTP error:
[        ]     | SocketException: OS Error: Connection timed out, errno = 110, address = pub.dartlang.org, port = 51688
[        ]     | 
[        ]     | dart:_http                                          _HttpClient.openUrl
[        ]     | package:http/src/io_client.dart 31:37               IOClient.send
[        ]     | package:pub/src/http.dart 66:43                     _PubHttpClient.send
[        ]     | package:http_retry/http_retry.dart 97:33            RetryClient.send
[        ]     | package:pub/src/http.dart 165:39                    _ThrowingClient.send
[        ]     | package:http_throttle/http_throttle.dart 33:31      ThrottleClient.send
[        ]     | ===== asynchronous gap ===========================
[        ]     | dart:async                                          _asyncThenWrapperHelper
[        ]     | package:http/src/base_client.dart 176:38            BaseClient._sendUnstreamed
[        ]     | package:http/src/base_client.dart 35:7              BaseClient.get
[        ]     | package:http/src/base_client.dart 125:28            BaseClient.read
[        ]     | package:pub/src/source/hosted.dart 187:31           BoundHostedSource._fetchVersions

even the website times out on firefox
Screenshot from 2020-12-12 20-42-53

Not working well

  var home = '/home/foo/';
  var path = '/bar';
  var absolutePath = p.join(home, path);
  // got /bar
  print(absolutePath); 

Exception: NoSuchMethodError: The method 'pathFromUri' was called on null.

I'm running into issues running flutter test- sometimes it's successful and other times it's not. I'm wondering if anyone has any ideas as to whether this is an issue on my end or not. Thanks.


This is an example of the output.

Shell: [ERROR:flutter/shell/testing/tester_main.cc(302)] Unhandled exception
Shell: Exception: NoSuchMethodError: The method 'pathFromUri' was called on null.
Shell: Receiver: null
Shell: Tried calling: pathFromUri(Instance of '_SimpleUri')
Shell: Stack trace: #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
Shell: #1      Context.fromUri (package:path/src/context.dart:1006:19)
Shell: #2      Context.prettyUri (package:path/src/context.dart:1068:28)
Shell: #3      prettyUri (package:path/path.dart:458:34)
Shell: #4      Frame.library (package:stack_trace/src/frame.dart:105:12)
Shell: #5      Frame.location (package:stack_trace/src/frame.dart:119:14)
Shell: #6      Chain.toString.<anonymous closure>.<anonymous closure> (package:stack_trace/src/chain.dart:256:33)
Shell: #7      MappedListIterable.elementAt (dart:_internal/iterable.dart:417:31)
Shell: #8      ListIterable.fold (dart:_internal/iterable.dart:195:30)
Shell: #9      Chain.toString.<anonymous closure> (package:stack_trace/src/chain.dart:257:12)
Shell: #10     MappedListIterable.elementAt (dart:_internal/iterable.dart:417:31)
Shell: #11     ListIterable.fold (dart:_internal/iterable.dart:195:30)
Shell: #12     Chain.toString (package:stack_trace/src/chain.dart:258:8)
Shell: #13     LazyChain.toString (package:stack_trace/src/lazy_chain.dart:32:31)
Shell: #14     RemoteException.serialize (package:test_api/src/util/remote_exception.dart:51:48)
Shell: #15     RemoteListener._sendError (package:test_api/src/remote_listener.dart:158:32)
Shell: #16     RemoteListener.start.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/remote_listener.dart:130:11)
Shell: #17     _rootRunBinary (dart:async/zone.dart:1222:13)
Shell: #18     _CustomZone.runBinary (dart:async/zone.dart:1107:19)
Shell: #19     runZonedGuarded.<anonymous closure> (dart:async/zone.dart:1601:18)
Shell: #20     _CustomZone.handleUncaughtError (dart:async/zone.dart:1076:19)
Shell: #21     Future._propagateToListeners (dart:async/future_impl.dart:610:16)
Shell: #22     Future._completeError (dart:async/future_impl.dart:537:5)
Shell: #23     Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:593:7)
Shell: #24     _rootRun (dart:async/zone.dart:1190:13)
Shell: #25     _CustomZone.run (dart:async/zone.dart:1093:19)
Shell: #26     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
Shell: #27     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
Shell: #28     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
Shell: #29     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
Shell:

I have put some logging in place and noticed that style is sometimes null during the execution, but not always which you can see below:
style.pathFromUri(_parseUri(uri))

flutter test test/integration-tests

00:02 +0: loading <path>/test/integration-tests/ui/apps/forgot_password_test.dart                                                                                                                                                                                         
STYLE: posix
00:03 +0: loading <path>/test/integration-tests/ui/apps/settings_test.dart                                                                                                                                                                                                
STYLE: posix
Shell: STYLE: null
Shell: [ERROR:flutter/shell/testing/tester_main.cc(302)] Unhandled exception
Shell: Exception: NoSuchMethodError: The method 'pathFromUri' was called on null.
Shell: Receiver: null
Shell: Tried calling: pathFromUri(Instance of '_SimpleUri')
Shell: Stack trace: #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
Shell: #1      Context.fromUri (package:path/src/context.dart:1006:19)
Shell: #2      Context.prettyUri (package:path/src/context.dart:1068:28)
Shell: #3      prettyUri (package:path/path.dart:458:34)
Shell: #4      Frame.library (package:stack_trace/src/frame.dart:105:12)
Shell: #5      Frame.location (package:stack_trace/src/frame.dart:119:14)
Shell: #6      Chain.toString.<anonymous closure>.<anonymous closure> (package:stack_trace/src/chain.dart:256:33)
Shell: #7      MappedListIterable.elementAt (dart:_internal/iterable.dart:417:31)
Shell: #8      ListIterable.fold (dart:_internal/iterable.dart:195:30)
Shell: #9      Chain.toString.<anonymous closure> (package:stack_trace/src/chain.dart:257:12)
Shell: #10     MappedListIterable.elementAt (dart:_internal/iterable.dart:417:31)
Shell: #11     ListIterable.fold (dart:_internal/iterable.dart:195:30)
Shell: #12     Chain.toString (package:stack_trace/src/chain.dart:258:8)
Shell: #13     LazyChain.toString (package:stack_trace/src/lazy_chain.dart:32:31)
Shell: #14     RemoteException.serialize (package:test_api/src/util/remote_exception.dart:51:48)
Shell: #15     RemoteListener._sendError (package:test_api/src/remote_listener.dart:158:32)
Shell: #16     RemoteListener.start.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:test_api/src/remote_listener.dart:130:11)
Shell: #17     _rootRunBinary (dart:async/zone.dart:1222:13)
Shell: #18     _CustomZone.runBinary (dart:async/zone.dart:1107:19)
Shell: #19     runZonedGuarded.<anonymous closure> (dart:async/zone.dart:1601:18)
Shell: #20     _CustomZone.handleUncaughtError (dart:async/zone.dart:1076:19)
Shell: #21     Future._propagateToListeners (dart:async/future_impl.dart:610:16)
Shell: #22     Future._completeError (dart:async/future_impl.dart:537:5)
Shell: #23     Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:593:7)
Shell: #24     _rootRun (dart:async/zone.dart:1190:13)
Shell: #25     _CustomZone.run (dart:async/zone.dart:1093:19)
Shell: #26     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
Shell: #27     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
Shell: #28     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
Shell: #29     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
Shell: 

Some additional info:
flutter doctor -v

flutter doctor -v
[✓] Flutter (Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-x64, locale en-US)
    • Flutter version 1.22.5 at /Users/nick/Code/flutter
    • Framework revision 7891006299 (3 weeks ago), 2020-12-10 11:54:40 -0800
    • Engine revision ae90085a84
    • Dart version 2.10.4

 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at /Users/nick/Library/Android/sdk
    • Platform android-29, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    • CocoaPods version 1.9.3

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 42.1.1
    • Dart plugin version 191.8593
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] VS Code (version 1.52.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.18.0

 
[!] Connected device                          
    ! No devices available

! Doctor found issues in 1 category.

Error: The method 'retype' isn't defined for the class Set<String>

Environment

Dart VM version: 2.0.0-dev.62.0 (Wed Jun 13 16:50:22 2018 +0200) on "macos_x64"

Steps to reproduce

> git clone https://github.com/dart-lang/site-webdev.git
> cd site-webdev
> pub upgrade
...
Precompiling executables...
Failed to precompile test:test:
file:///Users/chalin/.pub-cache/hosted/pub.dartlang.org/path-1.6.0/lib/src/path_set.dart:76:32: Error: The method 'retype' isn't defined for the class 'dart.core::Set<dart.core::String>'.
Try correcting the name to the name of an existing method, or defining a method named 'retype'.
  Set<T> retype<T>() => _inner.retype<T>();
                               ^

cc @kwalrath @kevmoo

flutter_test from sdk depends on path 1.8.0

Not sure if I should post this on the Flutter repo but it's impossible to upgrade to 1.8.1 with Flutter 2.8.1 • channel stable because of flutter_test.

Error message is:
Because every version of flutter_test from sdk depends on path 1.8.0 and [app_name] depends on path ^1.8.1, flutter_test from sdk is forbidden.

'absolute' gives wrong result when CWD is '/'; crash in 'relative'

Find below a test that fails on Linux as well as a proposed fix.
Only tested on Linux.

diff --git a/lib/path.dart b/lib/path.dart
index 8e87c33..f4748cb 100644
--- a/lib/path.dart
+++ b/lib/path.dart
@@ -91,10 +91,12 @@ String get current {
     return _current;
   } else {
     var path = uri.toFilePath();
-    // Remove trailing '/' or '\'.
+    // Remove trailing '/' or '\' unless it is the only thing left
+    // (for instance the root on Linux).
     var lastIndex = path.length - 1;
     assert(path[lastIndex] == '/' || path[lastIndex] == '\\');
-    _current = path.substring(0, lastIndex);
+    if (lastIndex > 0) _current = path.substring(0, lastIndex);
+    else _current = path;
     return _current;
   }
 }
diff --git a/test/io_test.dart b/test/io_test.dart
index f15f82d..251d91c 100644
--- a/test/io_test.dart
+++ b/test/io_test.dart
@@ -55,4 +55,30 @@ main() {
       io.Directory.current = dir;
     }
   });
+
+  test('absolute works on root working directory', () {
+    var orgDir = io.Directory.current.path;
+    try {
+      while (io.Directory.current.parent != null &&
+          io.Directory.current.parent.path != io.Directory.current.path) {
+        io.Directory.current = io.Directory.current.parent;
+      }
+      var dir = io.Directory.current.path;
+
+      // "path.relative(path.absolute('foo/bar'), from: dir)" currently crashes
+      // on Linux.
+      expect(path.relative(path.absolute('foo/bar'), from: dir),
+          path.relative(path.absolute('foo/bar')));
+
+      // On Linux this currently compares "foo/bar" and "/foo/bar".
+      expect(path.normalize(path.absolute('foo/bar')),
+          equals(path.normalize(path.join(dir, '../foo/bar'))));
+
+      // On Linux this currently compares "foo/bar" and "/foo/bar".
+      expect(path.normalize(path.absolute('foo/bar')),
+          equals(path.normalize(path.context.join(dir, '../foo/bar'))));
+    } finally {
+      io.Directory.current = orgDir;
+    }
+  });
 }

Deprecated API

Note: /Users/phuongphally/development/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.5.0/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
/Users/phuongphally/development/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.4+8/android/src/main/java/io/flutter/plugins/sharedpreferences/SharedPreferencesPlugin.java:25: warning: [deprecation] getFlutterEngine() in FlutterPluginBinding has been deprecated
    setupChannel(binding.getFlutterEngine().getDartExecutor(), binding.getApplicationContext());
                        ^
1 warning
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

Don't normalize relative()'s return value

Currently, relative() always normalizes its input. This seems to be the original intended behavior; it's even written into the tests. However, it adds a bunch of overhead for minimal value in cases where relativization should be cheap (for example if the path is already relative). It also goes against path's general principle of returning the user's original path when possible.

Normally a small behavioral difference like this in behavior that wasn't specified by the documentation could reasonably be included in a patch release. However, Since path is so widely-used, its stability expectations are higher than normal. As such, this should be treated as a breaking API change and saved until we decide to release path 2.0.0.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.