-
-
Notifications
You must be signed in to change notification settings - Fork 74
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
Fixing the lock file #52
Comments
Darn, that really is a problem I did not foresee. I probably did not notice this because I did not commit the lock file (yet) in the projects where I was using this. I'll have to think about that one for a bit... |
I'm having a hard time thinking of a clean way to fix this. Should the onus be on the user to temporarily disable studio and then run |
I guess ideally Studio would hook in right after |
I haven't looked into the implementation yet, but if the entries in composer.lock are generated by the repository instances that Composer uses, we might be able to fix this by using our own repository implementation, as hinted at in #56. |
@franzliedke that sounds like a great idea. So everyone is aware, these are the repositories in question: https://github.com/composer/composer/tree/master/src/Composer/Repository Looks like the default version is the Man, looking at that Edit: Actually I guess we have to be careful here as we should fall back to the repository that would it have used if Studio didn't exist. That might be something like a VCS repository (as is the case in our system). |
I'm having this exact same issue. I can't commit my lock file at the moment. I have no suggestions as I don't have enough programming skill to come up with a solution, but thanks for looking into this. |
So...until this is fixed, we have to manually edit
|
@mnpenner Out of curiosity, if you ran |
@mnpenner alternatively you can downgrade to an older version of studio ( |
@Lavoaster yes totally, Have changed install scripts on production servers to |
@warksit trouble with that is that |
I can't use version
The newer versions of this repo (anything post |
@swt83 unfortunately to continue using 0.9.5, you need to have version 1.0.0 of composer installed. There isn't really a good way around this at the moment. |
Why am I not able to get studio to work with version |
@swt83 so you're running the latest composer version and you've successfully run |
I'm not using the global method. I have the studio package installed on the project and I have the |
@janhartigan you're right. However |
I'll get back to you later today, sorry for the radio silence lately, folks. |
I think you guys know all this stuff already, but here is my report: I ended up removing Studio from my project and manually setting up a
I had to also manually add all my packages VCS dependencies to the master This was all a massive pain but it's got me up and running again. For whatever reason Studio says it's loading packages when I run |
@warksit hm strange. As I understand it,
How could it know where to get the repo, if not using the @swt83 hm must be a quirk of the non-global version. In the global version you just need to install it and have a Also...hi @franzliedke! No worries about the radio silence, if I really wanted to get anything done, I should just fix it myself and create a PR. |
@swt83 The structure of Can you post your studio.json, please? Also, if you run P.S.: Please open a new issue about this, it seems to be unrelated. |
Any news on this? Currently tiptoeing around the composer.lock related issue while sharing projects to teammates. Not a huge issue right now, but would like to see this streamlined a bit. :) |
Hi everyone, So I started using this package, but ran into this issue with I ended up removing the The concept is change the script to do;
This means composer has no idea and is completely unaffected by any local development. The only thing that will occur during step 2 is composer will detect your package is not actually in the vendor file, and re-download the current "latest" from packagist - but that is unlikely to be a big issue (especially as it'll probably be cached anyway). I've started using this for me - and it is working perfectly. The Maybe this concept could be used in this package? You could register each package as you currently do with Here are the commands I am using:
|
Hi @lioannou! I agree this is the best way forward. So, basically, Studio would always load all required projects via symlink, if it can find them locally, doing so after Composer does its usual thing and resolves the packages from Packagist etc. (this would probably still need the local repository as fallback, for when the package hasn't yet been added to Packagist). This leaves the question of what happens when a package is loaded via symlink - just because it is there -, despite not matching the version constraint defined in composer.json. Is it okay if we simply show a warning in that case? |
It could be a private VCS etc though. And people who want to develop a new package can create a local version otherwise.
Is it any different to what Studio already does though? You could do this:
That makes it visually explicit what packages have had there symlinks removed and/or re-add? |
This is actually the implementation that we've already done in our system. There are some issues with permissions (especially in Windows) if you use PHP's symlink. The scripts also handle the scenario where you try linking and it's already linked, and if you try unlinking when it's already unlinked. In the end we saw the fewest issues when just building the exec commands manually. You guys can use this if you find it useful. Here's are the scripts: <?php namespace App\Console\Commands;
use Illuminate\Console\Command;
class LinkDevelopmentCode extends Command {
/**
* The console command name
*
* @var string
*/
protected $name = 'api:link-dev-code';
/**
* The console command description
*
* @var string
*/
protected $description = 'Links the development code';
/**
* Execute the console command
*/
public function fire()
{
$targetPath = base_path('vendor' . DIRECTORY_SEPARATOR . 'path' . DIRECTORY_SEPARATOR . 'to' . DIRECTORY_SEPARATOR . 'api');
if (!$apiDevPath = env('API_DEVELOPMENT_PATH'))
return;
if (!is_dir($apiDevPath))
return $this->error("Could not find the API development path at {$apiDevPath}.");
//if this is a sym link, delete it
if (file_exists($targetPath) && $this->pathIsLink($targetPath))
{
exec($this->buildDeleteLinkCommand($targetPath));
$this->info("Existing symlink deleted");
}
//if this is a directory move it to its stored location
else if (is_dir($targetPath))
{
exec($this->buildMoveDirectoryCommand($targetPath));
$this->info("Original vendor path/to/api directory stowed in the closet");
}
exec($this->buildLinkCommand($apiDevPath, $targetPath));
$this->info("The symlink was created!");
}
/**
* Determines if the provided path is a symbolic link
*
* @param string $path
*
* @return bool
*/
protected function pathIsLink($path)
{
return is_link($path) || (array_diff(stat($path), lstat($path)));
}
/**
* Builds the OS-dependent symbolic linking command
*
* @param string $apiDevPath
* @param string $targetPath
*
* @return string
*/
protected function buildLinkCommand($apiDevPath, $targetPath)
{
if ($this->isWindows())
return "mklink /J {$targetPath} {$apiDevPath}";
return "ln -s {$apiDevPath} {$targetPath}";
}
/**
* Builds the OS-dependent link deletion command
*
* @param string $targetPath
*
* @return string
*/
protected function buildDeleteLinkCommand($targetPath)
{
if ($this->isWindows())
return "rd {$targetPath}";
return "rm {$targetPath}";
}
/**
* Builds the OS-dependent directory move command
*
* @param string $targetPath
*
* @return string
*/
protected function buildMoveDirectoryCommand($targetPath)
{
$newTargetPath = $targetPath . 'installed';
if ($this->isWindows())
return "move \"{$targetPath}\" \"{$newTargetPath}\"";
return "mv {$targetPath} {$newTargetPath}";
}
/**
* Determines if the current OS is Windows
*
* @return bool
*/
protected function isWindows()
{
return strpos(php_uname(), 'Windows') !== false;
}
} And here's the unlinking command: <?php namespace App\Console\Commands;
use Illuminate\Console\Command;
class UnlinkDevelopmentCodeCommand extends Command {
/**
* The console command name
*
* @var string
*/
protected $name = 'api:unlink-dev-code';
/**
* The console command description
*
* @var string
*/
protected $description = 'Unlinks the development API code';
/**
* Execute the console command
*/
public function fire()
{
$vendorPath = base_path('vendor' . DIRECTORY_SEPARATOR . 'path' . DIRECTORY_SEPARATOR . 'to' . DIRECTORY_SEPARATOR . 'api');
//if this is a sym link, delete it
if (file_exists($vendorPath) && $this->pathIsLink($vendorPath))
{
exec($this->buildDeleteLinkCommand($vendorPath));
$this->info("Existing API symlink removed");
}
//if the stored vendor path already exists, move it into its original location
if (file_exists($this->buildStoredVendorPath($vendorPath)))
{
exec($this->buildMoveDirectoryCommand($vendorPath));
$this->info("Original Composer API installation restored");
}
}
/**
* Determines if the provided path is a symbolic link
*
* @param string $path
*
* @return bool
*/
protected function pathIsLink($path)
{
return is_link($path) || (array_diff(stat($path), lstat($path)));
}
/**
* Builds the OS-dependent directory move command
*
* @param string $vendorPath
*
* @return string
*/
protected function buildMoveDirectoryCommand($vendorPath)
{
$storedVendorPath = $this->buildStoredVendorPath($vendorPath);
if ($this->isWindows())
return "move {$storedVendorPath} {$vendorPath}";
return "mv {$storedVendorPath} {$vendorPath}";
}
/**
* Builds the OS-dependent link deletion command
*
* @param string $vendorPath
*
* @return string
*/
protected function buildDeleteLinkCommand($vendorPath)
{
if ($this->isWindows())
return "rd {$vendorPath}";
return "rm {$vendorPath}";
}
/**
* Builds the vendor path location where the composer api installation is stored
*
* @param string $vendorPath
*
* @return string
*/
protected function buildStoredVendorPath($vendorPath)
{
return $vendorPath . 'installed';
}
/**
* Determines if the current OS is Windows
*
* @return bool
*/
protected function isWindows()
{
return strpos(php_uname(), 'Windows') !== false;
}
} |
This is a fundamental rewrite of the Composer integration. Now, instead of adding the loaded paths to Composer's search path (by creating path repositories for them), we replace the packages downloaded by Composer that can be found in the loaded paths by symlinks to the local paths. Doing so requires us to hook into the autoload dumper, which now has to respect the rules in the local path, not those obtained from Packagist. All of this should hopefully fix several issues, most importantly: - Composer's lock file will be written before Studio does its magic, therefore not causing any conflicts with other developers' setups. - Different version constraints on symlinked packages won't cause problems anymore. Any required packages that are found in loaded paths will be loaded, no matter the branch or version they are on. Open questions: - How should packages be handled that have not yet been added to Packagist? (Proposed solution: Create path repositories for the loaded paths, but *append* them instead of *prepending*, so that they will only be used as fallback, if Packagist does not yield any results.) - Should we validate the constraints from composer.json before creating symlinks? With this setup, everything might be working locally, but not when downloading the package from Packagist (as another version may be downloaded instead). Refs #52, #58, #65, #72.
Whew, that took a while. Another vacation passed. Sorry, guys. I worked on this, and I think I found a solution. Please try out the newly released 0.14.0-beta1 version. I am hoping this issue will be gone. (Note that you will have to run I am very tired right now, so let me just quote the commit message here:
Looking forward to your reports and your input. 😄 |
Any luck anyone? A simple "Seems to work" is welcome, too. And yes, the irony of me rushing all of you after taking so long myself is not lost on me. In case someone wondered. 😉 |
I can't get it to work (but it may be my fault, I'm unsure). Here's what I've done: I removed the
|
I'd also like to note that when I run "composer update" on the beta version, I'm not getting the "Loading path ..." message I always do. When I switch back to the old studio version, it appears again. |
@nathanmerrill Thanks for the feedback! Some notes:
|
My package is not registered on Packagist. The repo is included in the "repositories" section of my "composer.json", so it sounds like that that is what I'm waiting for. Thanks |
@franzliedke It works like a charm 👍 big thanks ❤️ BTW, it seems Studio only works for packages required with dev version, like |
One of my package can not be loaded... Reading /private/tmp/ddd/vendor/composer/installed.json
Writing lock file
Generating autoload files
Executing command (/Volumes/HDD/projects/php-packages/urlsafe-base64/): git branch --no-color --no-abbrev -v
Executing command (/Volumes/HDD/projects/php-packages/urlsafe-base64/): git log -n1 --pretty=%H
[Studio] Loading package elfsundae/urlsafe-base64-9999999-dev
Executing command (/Volumes/HDD/projects/php-packages/urlsafe-base64/): git branch --no-color --no-abbrev -v
Executing command (/Volumes/HDD/projects/php-packages/urlsafe-base64/): git log -n1 --pretty=%H
[Studio] Loading package elfsundae/urlsafe-base64-9999999-dev
[InvalidArgumentException]
Package elfsundae/urlsafe-base64-9999999-dev seems not been installed properly
Exception trace:
() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/Downloader/DownloadManager.php:156
Composer\Downloader\DownloadManager->getDownloaderForInstalledPackage() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/Downloader/DownloadManager.php:294
Composer\Downloader\DownloadManager->remove() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/Installer/LibraryInstaller.php:213
Composer\Installer\LibraryInstaller->removeCode() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/Installer/LibraryInstaller.php:126
Composer\Installer\LibraryInstaller->uninstall() at /Volumes/HDD/projects/github/studio/src/Composer/StudioPlugin.php:72
Studio\Composer\StudioPlugin->symlinkStudioPackages() at n/a:n/a
call_user_func() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php:171
Composer\EventDispatcher\EventDispatcher->doDispatch() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/EventDispatcher/EventDispatcher.php:96
Composer\EventDispatcher\EventDispatcher->dispatchScript() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/Installer.php:321
Composer\Installer->run() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/Command/UpdateCommand.php:159
Composer\Command\UpdateCommand->execute() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/vendor/symfony/console/Command/Command.php:266
Symfony\Component\Console\Command\Command->run() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/vendor/symfony/console/Application.php:861
Symfony\Component\Console\Application->doRunCommand() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/vendor/symfony/console/Application.php:208
Symfony\Component\Console\Application->doRun() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/Console/Application.php:245
Composer\Console\Application->doRun() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/vendor/symfony/console/Application.php:127
Symfony\Component\Console\Application->run() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/src/Composer/Console/Application.php:100
Composer\Console\Application->run() at phar:///usr/local/Cellar/composer/1.5.5/libexec/composer.phar/bin/composer:54
require() at /usr/local/Cellar/composer/1.5.5/libexec/composer.phar:24
update [--prefer-source] [--prefer-dist] [--dry-run] [--dev] [--no-dev] [--lock] [--no-custom-installers] [--no-autoloader] [--no-scripts] [--no-progress] [--no-suggest] [--with-dependencies] [-v|vv|vvv|--verbose] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [-i|--interactive] [--root-reqs] [--] [<packages>]... |
@ElfSundae, @nathanmerrill : I've got the same issue with the beta version. But my package is not loaded twice :
|
@PapsOu try: rm -rf vendor
composer update --no-autoloader
composer dump-autoload |
@ElfSundae : Hum, it works, but composer trigger symfony post script, that fails because autoload is not generated :-D |
What is your |
@ElfSundae : https://github.com/libre-informatique/LISemSymfonyProject/blob/wip-platform/composer.json But that's normal, all symfony 2/3 projects have these post-scripts (that uses symfony commands) |
@PapsOu You can rename
|
Hum, this solution doesn't seems to be a good one. I'll prefer wating a stable release of Studio (with the usage of |
In no case should we touch |
Unfortunately
|
tried the 0.14.0-beta1 again on another project and
|
Chiming in here that I am getting the same error as @weitzman |
I put together a few fixes from the master branch and some other comments I've seen in the issue queue. My team have been using 0.14.0-beta3 of this package, and have had no issues with "seems not been installed" errors. We've also resolved the need for dump-autoload, and we can install/create symlinks with composer install quite happily. https://github.com/annikaC/studio-fixed |
@annikaC, have you perchance created a PR with some fixes @franzliedke might consider? |
Yep, these fixes were made before Composer 2 came out. Will have to reroll over the latest master. |
Still no usable fix? :( |
This is so useful! I really appriciate all the work Studio got in the past. But also for me, it is daily frustrating to clean up |
I have my own composer-link https://github.com/SanderSander/composer-link which tries overcomes the issues. |
@SanderSander I was just able to test your composer-link package and it is awesome! Thank you so much for the note. Now looking forward to have wildcard folder support. For everyone here who needs a simple and fast solution to link Composer packages from different paths, have a look at this. |
We've been struggling with this as well and created a new Composer plugin https://github.com/ALDIDigitalServices/ComposerPackageDevelopmentToolset. Feedback appreciated. |
Hey @franzliedke thanks a lot for taking the time to put together the recent release.
However, I have noticed one significant issue with the newly-generated
composer.lock
file. Normally composer generates something like this:There would also be a
dist
with the zipped contents of the git repo.With the new updates, the composer lock file now looks like this:
Trouble with this is that when we push the code up through the pipeline, our servers will try to install that
composer.lock
file and it won't be able to figure out how to grab the dist. Since you're already using this in a real project, I'm guessing there's some other approach that I'm missing. Let me know what you think.The text was updated successfully, but these errors were encountered: