pubspec.lock is different between Windows and Unix if path reference is used

Created on 6 Jun 2015  路  22Comments  路  Source: dart-lang/pub

Issue by Fox32
_Originally opened as dart-lang/sdk#18097_


What steps will reproduce the problem?

  1. Add a dependency to a package by path to pubspec.yaml:

  xyz:
    path: ../xyz

  1. Run pub get

What is the expected output? What do you see instead?

Using Windows, the following part is added to the pubspec.lock:

  xyz:
    description:
      path: "..\xyz"
      relative: true
    source: path
    version: "0.9.0"

If I put the file into version control, I get problems using it in combination with a Unix system, like OSX. OSX expect the following lines:

  xyz:
    description:
      path: "../xyz"
      relative: true
    source: path
    version: "0.9.0"

What version of the product are you using? On what operating system?

Dart Editor version 1.3.0.dev_07_10 (DEV)
Dart SDK version 1.3.0-dev.7.10

Please provide any additional information below.

Maybe the pubspec.yaml should always be outputed with normal '/', even on Windows, to make it more compatible.

enhancement

Most helpful comment

Is there any reason for path dependencies we shouldn't just directly use the value supplied in the pubspec.yaml, without modification at all? It seems like that would be the most flexible and simple approach which I believe would solve this problem.

All 22 comments

Comment by kevmoo


_Added Area-Pub, Triaged labels._

Comment by nex3


Path dependencies are fundamentally non-portable and platform-dependent. If you're sharing code across computers and especially across operating systems, you should use git or hosted dependencies.

We could store paths in the lockfile as file: URIs, which would make a subset of relative paths work across platforms, but I don't know that it's worth such a partial solution to the problem.

Comment by Fox32


Is there a way to use hosted or git dependencies with some sort of authentication? Our current workaround is a additional git repository that is handled externally and is added as a path dependency.
The problem with this workaround is that it requires that every user check the repository the same way. Thats not really good. Till now we tried to not use multiple packages at all, but now we require a second package.

Any idea how to handle this in a better way?

Comment by nex3


Git is very flexible in the number of protocols it supports. You can use private GitHub repositories to support authentication, or host a git repository on your own server behind either SSH or HTTP authentication. If you have a local network that's not accessible externally, you could also host a git repository there.

Comment by Fox32


That is what we tried first:

  1. Add a git dependency:
    packagename:
      git: http://username@computer/spackagename.git
  2. Run pub get
  3. Pub get asks for your password, enter it
  4. Pub asks for the password again, enter it again
  5. Pub exits with error message:
    Error in pubspec for package "packagename" loaded from ..\Pub\Cache\git\packagename-HEAD\pubspec.yaml:
    Could not find a file named "pubspec.yaml" in "..\Pub\Cache\git\packagename-HEAD".

It looks like it does not accept the password for some reasons, but that would be a seperate issue. I don't get any password request at all if I run pub get from the editor.

Comment by nex3


What do the contents of ..\Pub\Cache\git\packagename-HEAD look like? How about ..\Pub\Cache\git? Can you include the result of installing from that git URL with --trace?

I've filed issue dart-lang/sdk#18224 to track editor support for using credentials with git repositories.

Comment by Fox32


The packagename-HEAD folder is empty, except the .git sub folder. The .git folder doesn't look broken on the first view, but operations like "git branch" are not returning the correct results (they return no branches).

I thought before starting the whole process with --trace, I it would make scense cleanup the directories first to have a fresh start. Now I can't repoduce it anymore... On the other side it already happend on multiple devices? I create a issue if it happens again.

I had to type in my password 5 times, thats not really useable, but I don't think their is a better solution for that. After that I tried the ssh based way, but I also had to enter the private key password multiple times.

I think for now we stay with the path dependencies as a simple solution. But later we have to think about it again.

Comment by nex3


If you use SSH authentication with an authentication key, you can authenticate once with a local daemon and avoid typing your password for future connections. Setting that up is outside the scope of this bug, though.


_Added WontFix label._

_This comment was originally written by xavier.hai...@gmail.com_


I would like to reopen this bug.
I think this is very justified to use path dependencies even when working with multiple platforms.

We have a single git repository that contains a lot of packages which reference each other with relative path. ie:

  • common
  • net (reference common with path: ../common)
  • proj1 (reference net with path: ../net)
  • proj2...

We don't want to host each package separately because it represent a single solution that we split for convenience.

The changes in the pubscpec.lock that appears when someone commit from windows or from mac is only noise that we would like to remove.

Comment by nex3


If you're using dependencies that are so tightly-coupled as to always be in the same repository, putting them in different packages seems like the wrong architecture. Packages primary exist for versioning, and if you're using them over the long term in an unversionable environment you're already working against the grain of the system. I don't think it makes sense to add this feature to support that sort of environment.

Comment by jtalley


I'm frustrated at the short sighted answer of WontFix on this. There are many reasons for splitting code into multiple packages. Multiple packages is completely valid because Dart specifies access control (private members) at the package level. Deferred loading is yet another reason to be using multiple packages. Large code bases need organization, control, structure. Large code bases are also developed by large teams, which means more development platform diversity. Other tools handle this issue. Fix this!

Comment by nex3


Issue #1221 has been merged into this issue.

Comment by nex3


There's nothing stopping you from using multiple packages. If you want them to be portable across multiple machines, though, you'll need to put them in separate repositories or separate hosted packages.

Dart specifies access control (private members) at the package level. Deferred
loading is yet another reason to be using multiple packages.

This isn't accurate. The Dart language has no notion of packages. All access control and deferred loading is library-level.

Large code bases need organization, control, structure.

It's perfectly possible to organize your code within a single package. Packages are units of distribution first, and organization second.

Comment by munificent


If the path in the lockfile is relative, I personally think it would be good to have it use forward slashes. That's compatible with both Windows and POSIX. Relative path packages are pretty common, and it seems like a shame to make them less portable when the fix is simple. We already have plenty of special-case code for relative versus absolute paths, so I don't think it's too much of a pain to add a little more.

I'm re-opening this, but we can talk about in person if you want Natalie.


_Added Triaged label._

Comment by jtalley


This isn't accurate. The Dart language has no notion of packages. All access control and deferred loading is library-level.

Yes, I meant library when I said package. That doesn't change the validity of needing multiple libraries and wanting to organize multiple libraries in one repo. The language should not dictate source control usage patterns.

Comment by nex3


I would be okay with changing this specifically for relative paths, although even then there are edge cases that won't work across platforms.

Yes, I meant library when I said package. That doesn't change the validity of needing
multiple libraries and wanting to organize multiple libraries in one repo. The language
should not dictate source control usage patterns.

What's wrong with making the entire repo one package? A package can contain more than one library.

Comment by jtalley


What's wrong with making the entire repo one package? A package can contain more than one library.

Multiple independent but related apps and a shared set of libraries in one repo.

Comment by paulevans-sonar


Was about to report this issue then rediscovered this bug.
It is very irritating having the path in the pubspec.lock yaml change to the native os each time it rebuilds. Means you have to revert the file every time you check something in if you differ from the source by \ / flipping only.

Three and a half years later this is still an issue. Any updates?

Is there any reason for path dependencies we shouldn't just directly use the value supplied in the pubspec.yaml, without modification at all? It seems like that would be the most flexible and simple approach which I believe would solve this problem.

This is not limited to path dependencies and even happens if both machines have windows, i have no path deps on a company project yet pubspec seems to change from time to time and git diffs show CRLF - LF changes.
And yes, git.autocrlf is configured accordingly in both machines.

EDIT: Clarification

Since https://github.com/dart-lang/pub/pull/2299 we always use '/' for relative paths in pubspec.lock.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amirh picture amirh  路  20Comments

jayoung-lee picture jayoung-lee  路  38Comments

JSanford42 picture JSanford42  路  21Comments

Scorpiion picture Scorpiion  路  24Comments

kevmoo picture kevmoo  路  53Comments