nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.44k stars 1.47k forks source link

nimble lock: causes Nim to no longer find packages #22438

Open ee7 opened 1 year ago

ee7 commented 1 year ago

Short example

$ nim c src/foo.nim # success, where `foo.nim` contains `import jsony`
$ nimble lock
$ nim c src/foo.nim

Current output

/tmp/foo/src/foo.nim(1, 8) Error: cannot open file: jsony

Expected output

No error. I thought that Nim would just ensure that it uses the package versions from the nimble.lock file.

Discussion

Is this intended? I am aware of https://github.com/nim-lang/Nim/commit/7c6dcfd968867ec9b2fee5ca3ef8f251a6faa350 and https://github.com/nim-lang/nimble/issues/1004.

Is the intention that after running nimble lock:

The same error also breaks e.g. nimble test, if you redefine the test task for performance like:

task test, "Run all the tests":
  exec "nim r tests/all_tests.nim"

NIMBLE_DIR is not set.

Nim version

Nim Compiler Version 2.0.0 [Linux: amd64]
Compiled at 2023-08-01
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: a488067a4130f029000be4550a0fb1b39e0e9e7c
active boot switches: -d:release

Long example

nimble lock produces an error if the project is not under version control. So please excuse the boilerplate below - I've tried to make a clear, robust reproduction.

#!/usr/bin/env bash

set -ex

# Create nimble project
cd /tmp
rm -rf /tmp/foo
mkdir -p foo
cd foo
nimble --silent -y init
git init
# Make `git commit` work even if there's no global git user.name or user.email
git config user.name "Foo"              # Does not alter global settings
git config user.email "foo@example.org" # Does not alter global settings
git add .
git commit --quiet -m 'initial commit'

# Add jsony dependency
rm src/foo.nim
echo 'import jsony' > src/foo.nim
nimble install jsony
nim c src/foo.nim                       # Success, before running `nimble lock`
echo 'requires "jsony"' >> foo.nimble
nimble path jsony                       # Prints the absolute path of the installed jsony

# Add lock file
nimble lock
git add .
git commit --quiet -m 'another commit'  # Show that committing the lock file doesn't prevent the error 
nim c src/foo.nim                       # Error

So we have the foo.nimble file:

# Package

version       = "0.1.0"
author        = "Anonymous"
description   = "A new awesome nimble package"
license       = "MIT"
srcDir        = "src"

# Dependencies

requires "nim >= 2.0.0"
requires "jsony"

and the nimble.lock file:

{
  "version": 2,
  "packages": {
    "jsony": {
      "version": "1.1.5",
      "vcsRevision": "ea811bec7fa50f5abd3088ba94cda74285e93f18",
      "url": "https://github.com/treeform/jsony",
      "downloadMethod": "git",
      "dependencies": [],
      "checksums": {
        "sha1": "6aeb83e7481ca8686396a568096054bc668294df"
      }
    }
  },
  "tasks": {}
}

Current output

[...]
$ nim c src/foo.nim
Hint: used config file '/home/ee7/.choosenim/toolchains/nim-2.0.0/config/nim.cfg' [Conf]
Hint: used config file '/home/ee7/.choosenim/toolchains/nim-2.0.0/config/config.nims' [Conf]
Hint: used config file '/home/ee7/.config/nim/nim.cfg' [Conf]
........................................................................................................
/tmp/foo/src/foo.nim(1, 8) Warning: imported and not used: 'jsony' [UnusedImport]
51405 lines; 1.177s; 71.148MiB peakmem; proj: /tmp/foo/src/foo.nim; out: /tmp/foo/src/foo.out [SuccessX]
$ echo 'requires "jsony"' >> foo.nimble
$ nimble path jsony
/home/ee7/.nimble/pkgs2/jsony-1.1.5-6aeb83e7481ca8686396a568096054bc668294df
$ nimble lock
     Info:  Generating the lock file...
  Verifying dependencies for foo@0.1.0
     Info:  Dependency on jsony@any version already satisfied
  Verifying dependencies for jsony@1.1.5
  Success:  The lock file is generated.
$ git add .
$ git commit --quiet -m 'another commit'
$ nim c src/foo.nim
Hint: used config file '/home/ee7/.choosenim/toolchains/nim-2.0.0/config/nim.cfg' [Conf]
Hint: used config file '/home/ee7/.choosenim/toolchains/nim-2.0.0/config/config.nims' [Conf]
Hint: used config file '/home/ee7/.config/nim/nim.cfg' [Conf]
......................................................................
/tmp/foo/src/foo.nim(1, 8) Error: cannot open file: jsony

Expected output

No error at the end.

Clonkk commented 1 year ago

Try nimble setup after running nimble lock

ee7 commented 1 year ago

@Clonkk Thanks. That's what I was missing. It was apparently hard for me to discover.

So I guess it's intended that nimble lockdoesn't automatically do the nimble setup stuff? If so, someone please close this.

But I'd suggest that we could:

  1. Mention nimble setup in the nimble lock section of the nimble docs
  2. Consider adding "you might want to run nimble setup" to the output of nimble lock
arnetheduck commented 1 year ago

Is this intended?

in general, locking means that you want some particular dependencies and only those dependencies - otherwise, random stuff from random nimble PATH:s can interfere with import.

That said, seems reasonable that lock should imply setup, though this would be a reasonable issue to raise in https://github.com/nim-lang/nimble/ instead

cc @yyoncho -