-
-
Notifications
You must be signed in to change notification settings - Fork 10
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
Yarn on Linux resolves to "wrong" global package folder #13
Comments
@byCedric I promised to help so I spent some time digging through yarn source and here is what I was able to figure out (in random order): global package dirOfc there isn't a single documentation page inside wonderful yarn docs that lists all possible configuration values so you can only dig through source code in order to figure out that global package dir is determined in following manner: this.globalFolder = opts.globalFolder || String(this.getOption('global-folder', true));
if (this.globalFolder === 'undefined') {
this.globalFolder = constants.GLOBAL_MODULE_DIRECTORY;
} where
Because nobody really knows that, it will typically default to export const GLOBAL_MODULE_DIRECTORY = path.join(DATA_DIRECTORY, 'global'); You see this and think: ok that makes sense. I got: const getYarnHomeDir = () => {
if (isWindows || !process.getuid) {
return os.homedir();
}
const isRootUser = process.getuid() === 0;
return isRootUser ? path.resolve('/usr/local/share') : os.homedir();
};
const getYarnDataDir = () => {
if (isWindows) {
if (process.env.LOCALAPPDATA) {
return path.join(process.env.LOCALAPPDATA, 'Yarn/Data');
}
return path.join(getYarnHomeDir(), '.config/yarn');
}
if (process.env.XDG_DATA_HOME) {
return path.join(process.env.XDG_DATA_HOME, 'yarn');
}
return path.join(getYarnHomeDir(), '.config/yarn');
}; Long story short, in order to reliably determine global package dir one needs to:
Where 2. and 3. are especially funky having in mind that (which is ofc undocumented, why bother documenting it...) yarnpkg/yarn#3320 (comment) yarn uses custom rc format also known as "stringified lockfiles" (I didn't invented that, I swear: yarnpkg/yarn#4134 (comment)) so you can't really pull it through ini parser. In order to fight that insanity I made some hacky wrapper around ini parser: const readYarnrc = filePath => {
try {
const contents = fs.readFileSync(filePath, 'utf8');
const lines = contents.split(/\r?\n/g);
const rePrefix = /^(?:--)?prefix\s+/;
const prefix = lines.reduce((prefix, line) => {
line = line.trim();
return rePrefix.test(line) ? line.replace(rePrefix, '') : prefix;
}, undefined);
if (prefix) {
return ini.parse(`prefix=${prefix}`).prefix;
}
} catch (_) { }
}; that serves me well so far 🤞 I said earlier that you have to calculate const getYarnGlobalPrefix = () => {
if (process.env.PREFIX) {
return process.env.PREFIX;
}
if (isWindows) {
return path.dirname(process.execPath);
}
const prefix = path.dirname(path.dirname(process.execPath));
return path.join(process.env.DESTDIR || '', prefix);
}; I said it's not real Now; going back to current state of art that is present inside That's it for now. Stay tuned for next episode of @vladimyr fighting yarn with working title |
Haha wow @vladimyr, you do your research thoroughly and I like it ❤️ Thanks for helping/checking this out! It's insane how Yarn does this right now. I imagine a developer at Yarn, who put the "lovely comment" above, looking at that and thinking "naa, I'm not touching that..." 😅 If there is anything I can help with, spam me and I'll appear! |
@byCedric has funded $50.00 to this issue.
|
I personally love it to get this fixed, so I'm throwing in some funds so it can get attention 😄 Hope it's not to much pressure though! |
I think I found the cause of problem and I believe macOS also has the same problem. @byCedric What output of |
@TiagoDanin I get this 😄
|
I don't do this because of funds but I don't have problem with it either, I don't mind really. If it were up to me I'd have better ideas how to waste few dozen bucks and they mostly revolve around good food and beverage 😁 No pressure made it is just that I don't have enough time lately to tackle this but I'll give my best to finish it this weekend 🤞 |
Nice! yarn/src/cli/commands/global.js L120-123 this can help you |
Oooh god, what a read and insanity... :D Btw, it's strange to get different results, since both linux and macos does not go to the
That's why I proposed there (yarnpkg/yarn#5806) to add few real ENV variables, so we can get it easily. |
It is been a while and I forgot all delicate intricacies of yarn internals but I haven't changed my opinion and feelings towards yarn's way of doing things. That being said hard things will always remain hard. There isn't and should not be any magical shortcut. If you need to figure out yarn's global dirs you need to go through same steps that yarn does. @tunnckoCore I'm sympathetic to your cause 👍 but I can't give you 👍 for proposed solution because it breaks canonical rules. Environment (variables) control behavior of a program not other way around. We would end up in huge mess if every binary starts to modify environment per its needs. User is and should always be in control of an environment while binaries could adapt to it if needed. Asking for yarn to pollute environment with environment variables that aren't effectively under user's control (at least aren't created by user) is essentially asking for it to behave wildly non-standard and something that will likely never be implemented. If you want to get some info from yarn you need to ask it by invoking it. yarn isn't and does not provide init shell script that you'll invoke as part of your shell profile and that would be the only place where temporary modification (per session) of environment can be considered allowed. What you proposed can be done only if yarn installer starts modifying your shell profile and/or env config and that is big no no due to reasons explained earlier. Correct me if I did not understand you correctly. |
Agree. But many programs is doing that while installation - not that many but still. Yes, this doesn't help in the other cases when you install it through package manager or such, but still one case less to care in such issues like this one. Also, adding 1 or 2 env variables isn't really that big pollution.
Anyway, you are correct to some extent. |
For example?
So you are envisioning something like:
which is basically reinventing
It is not matter of a quantity it is about how you are planning to do that in the first place. I may be wrong but I believe it is technically impossible to do that in transparent and widely accepted manner. 🤔 |
It looks like Yarn is resolved to a "wrong" global directory on Linux. On my MacOS/OSX this works perfectly though.
OSX:
Linux (through
docker run -v $PWD:/code -w /code node:10 npx ava
):I don't think the
/usr/local/global
is the proper folder for yarn right? When I manually add something globally through Yarn on the docker/linux instance, I get this path:IssueHunt Summary
Sponsors (Total: $50.00)
Become a sponsor now!
Or submit a pull request to get the deposits!
Tips
The text was updated successfully, but these errors were encountered: