dart-lang / pub

The pub command line tool
https://dart.dev/tools/pub/cmd
BSD 3-Clause "New" or "Revised" License
1.04k stars 226 forks source link

Pub global activate with local path sometimes has no effect #4295

Open matthew-carroll opened 4 months ago

matthew-carroll commented 4 months ago

Environment

Dart SDK version: 3.4.1 (stable) (Tue May 21 15:46:25 2024 +0000) on "macos_arm64"

macOS 14.3.1

No

Problem

I maintain a CLI package. There's the published version on Pub, and then there's version that I work on locally.

When I want to activate the Pub version, I use dart pub global activate static_shock_cli.

When I want to activate the local version, I set the current working directory to where that package is defined and then I run dart pub global activate --source=path .

Expected behavior

When I activate the local version, the local version should run when I issue commands.

Actual behavior

The Pub version continue to be run when I try execute commands.

Details

On a seemingly random basis, I'm unable to effectively activate my local version. There's no error when I try to activate my local version. The output suggests success. However, when I go to run the tool, it clearly doesn't have any of my local changes - it's still running the version from Pub.

When this happens, I also explicitly run dart pub global deactivate static_shock_cli before then trying again to activate the local version. This has no effect. Pub somehow still ends up executing the Pub version, which I just told it to deactivate.

I've discovered that if I delete all the references I can find in my Pub cache for this package, then I can get Pub to truly activate my local version. But that's the level of intervention it seems to take to get this working.

One final detail is that I primarily work with Flutter. That's where my Dart distribution comes from. I occasionally switch between the master branch and stable branch of Flutter. It's possible that at times I end up activating the local version of my CLI package when I'm on master and other times on stable. However, if my local package isn't activating, and I realize that I'm on master, even if I then switch to stable, the problem persists. The only way out seems to be to manually delete directories out of the pub cache.

sigurdm commented 4 months ago

This sounds like a bug. Not sure how it can happen.

Any help you can give with reproducing this would be nice.

If you could attach the output of running dart pub --verbose global activate --source=path . in the case where it fails to update the activated version, that would be great.

matthew-carroll commented 4 months ago

Ok, I'll have to wait until it randomly happens again.

eripoll commented 2 months ago

I seem to have the same issue. dart pub global activate --source path .

Resolving dependencies... 
Downloading packages... 
  _fe_analyzer_shared 68.0.0 (72.0.0 available)
  analyzer 6.5.0 (6.7.0 available)
  macros 0.1.0-main.0 (0.1.2-main.4 available)
  very_good_analysis 5.1.0 (6.0.0 available)
Got dependencies!
4 packages have newer versions incompatible with dependency constraints.
Try `dart pub outdated` for more information.
Package sfdk_cli is currently active at path ".../sfdk_cli".
Installed executable sfdk_cli.
Activated sfdk_cli 0.0.2 at path ".../sfdk_cli".

which is expected (except for the dependencies issues)

Run sfdk_cli --version I get 0.0.1

The activate source doesn't seem to do anything anymore since I updated to Flutter latest stable version

UPDATE: I'm adding the pub_log.txt linked to my last activate test. pub_log.txt

eripoll commented 2 months ago

@sigurdm ⏫

sigurdm commented 2 months ago

Weird. The attached log says MSG : Activated sfdk_cli 0.1.0 at path "/Users/e******l/Dev/before/sfdk_cli". not 0.0.2 as what you pasted... Also not 0.0.1 as you got in the version output.

Not sure what to make of this...

eripoll commented 2 months ago

Oh sorry, Yes let me explain. The log file I shared is from my actual package. What I mentioned above was from a brand new project as I was trying to reproduce the bug in a blank project to see if I could reproduce. Sorry for not explaining this, @sigurdm

sigurdm commented 2 months ago

Sorry, I'm not following.

Did you manage to reproduce in the blank project?

eripoll commented 2 months ago

Yes I did, @sigurdm . No matter which project, whether a fully-fledged one or a blank one, I have the same issue. Each time I activate, it stays on the previous version,

matthew-carroll commented 2 months ago

I just ran into this again. I discovered that I have to delete the .dart_tool directory within my CLI package to get it to build fresh.

When I delete the .dart_tool directory, and activate from source, the next invocation of my CLI command explicitly shows a recompilation:

Resolving dependencies in `/Users/admin/Projects/static_shock/static_shock/packages/static_shock_cli`... 
Downloading packages... 
Got dependencies in `/Users/admin/Projects/static_shock/static_shock/packages/static_shock_cli`.
Building package executable... (1.6s)
Built static_shock_cli:static_shock_cli.

If I don't delete the .dart_tool directory then the above build output isn't shown, and any new behaviors I added since the last activation doesn't exist in the binary.

Specifically, within the .dart_tool directory, deleting the .snapshot file is what makes the difference.

SandPod commented 2 weeks ago

We at Serverpod (and contributors to our framework) are experiencing the same issue. I can +1 @eripoll that this is reproducible in a newly created empty project.

This is usually my workaround:

On Mac, I can find out where the cached binary is stored by running:

$ which serverpod
-> /Users/alex/.pub-cache/bin/serverpod
$ cat /Users/alex/.pub-cache/bin/serverpod
-> 
#!/usr/bin/env sh
# This file was created by pub v3.5.1.
# Package: serverpod_cli
# Version: 2.1.0-beta.3
# Executable: serverpod
# Script: serverpod_cli
if [ -f /Users/alex/.pub-cache/global_packages/serverpod_cli/bin/serverpod_cli.dart-3.5.1.snapshot ]; then
  dart "/Users/alex/.pub-cache/global_packages/serverpod_cli/bin/serverpod_cli.dart-3.5.1.snapshot" "$@"
  # The VM exits with code 253 if the snapshot version is out-of-date.
  # If it is, we need to delete it and run "pub global" manually.
  exit_code=$?
  if [ $exit_code != 253 ]; then
    exit $exit_code
  fi
  dart pub -v global run serverpod_cli:serverpod_cli "$@"
else
  dart pub global run serverpod_cli:serverpod_cli "$@"
fi

And then manually remove the file /Users/alex/.pub-cache/global_packages/serverpod_cli/bin/serverpod_cli.dart-3.5.1.snapshot

jsiedentop commented 4 days ago

With macOs I have the same issue.

I update my dart tool with, the following command, but it doesn't work.

dart pub global activate --source path . --overwrite

When I run my tool it's actually a shell script, that will be executed and the content makes clear, that if there is a snapshot with the current dart version, the snapshot will be executed instead of the latest version from the source directory.

# /Users/<user>/.pub-cache/bin/<tool>
# The content of the script is
if [ -f /Users/<user>/src/<tool>/bin/main.dart-3.5.2.snapshot ]; then
  dart "/Users/<user>/src/<tool>/bin/main.dart-3.5.2.snapshot" "$@"
  # The VM exits with code 253 if the snapshot version is out-of-date.
  # If it is, we need to delete it and run "pub global" manually.
  exit_code=$?
  if [ $exit_code != 253 ]; then
    exit $exit_code
  fi
  dart pub -v global run <tool>:<tool> "$@"
else
  dart pub global run <tool>:<tool> "$@"
fi

Deleting the old snapshot was also my first approach, but it's also possible to run the tool via dart pub global run <tool>:<tool> to update the snapshot.

So my current workaround to update the tool is:

dart pub global activate --source path . --overwrite
dart pub global run <tool>:<tool>

My guess why the bug does not always occur: After updating the dart vm, the first run of the tool will create a new snapshot. However, a second attempt to update the tool fails. I would expect, that dart pub global activate should always recreate the snapshot to make sure, that the latest changes will be applied.