Nim: Unify all --version of Nim tools

Created on 24 Mar 2020  路  6Comments  路  Source: nim-lang/Nim

Unify all --version of Nim tools

While building a simple script that needs to collect the versions of all the tools that come with Nim,
I noticed all of them have different outputs for the --version that should be as simple as possible,
as the best practices recommend, easy to interoperate with other tools and user made scripts,
can be less code to maintain because it can be made into 1 template thats used everywhere,
some tools seen big refactors without any version bump making having a version pointless by definition,
and can even be more testable and documentable if a simple uniform way is choosen.

  • nim --version
Nim Compiler Version 1.1.1 [Linux: amd64]
Compiled at 2020-03-24
Copyright (c) 2006-2019 by Andreas Rumpf

active boot switches: -d:release

Copyright is years out of date.


  • nimble --version
nimble v0.11.0 compiled at 2020-03-24 10:41:25
git hash: couldn't determine git hash

Shows a Git error.


  • testament --version

Testament fails, it has no --version argument.

  • nimsuggest --version
Nim Compiler Version 1.1.1 [Linux: amd64]
Compiled at 2020-03-24
Copyright (c) 2006-2019 by Andreas Rumpf

active boot switches: -d:release -d:danger --gc:markAndSweep

Nimsuggest says it is the Nim Compiler ?.
Copyright is years out of date.


nimpretty and nimgrep do it Ok.

Suggested Format

  • Version SemVer + "\n"
  • Version SemVer + "\n" + Git Short Hash + "\n"

All other stuff like compile options and memes should go into --help.

Easy to parse with simple code, even at compile-time.

It can be actually less code to maintain, something like:

template showVersion() = quit("1.2.3", 0)

Alternative Solution

Just assume that all Tools that come with Nim just follow the same Version as Nim itself, and dont have to maintain this ever again:

template showVersion() = quit(NimVersion, 0)
Low Priority

Most helpful comment

counter proposal

human readable output should not be used for machine consumption . It's meant for ease of read, not ease of parsing, and is subject to backward incompatible changes.

instead of unifying tool --version, we should unify on tool --dump which dumps json, like nim dump already does, eg:

nim dump --dump.format:json . # dump all as json
nim dump --dump.format:json .| jq .lib_paths # just show 1 key (requires jq)
nim --dump # (easy PR away, avoids running cfg/nims files when no filename specified)
nim --dump --dump.key:lib_paths # (easy PR away, avoids jq)

This is the analog of git's plumbing mode (for machine consumption) vs porcelain mode (for human consumption).

  • git hash should indicate whether it's dirty or not, as done in some other tools:
git hash: c0dbcffca643ac79e0c03c9509e92f5841b38a94
=>
git hash: c0dbcffca643ac79e0c03c9509e92f5841b38a94 # git status was clean
git hash: c0dbcffca643ac79e0c03c9509e92f5841b38a94-dirty # git status was not clean

this only affects locally built nim, and helps distinguish whether the hash indicates a reproducible state or not.

for json dump output, dirty bit could be a separate bool field in json output.

rationale

a serialization format like json (or something with a schema, eg protobuf etc) is universal, trivial to parse, and more importantly json output can be augmented with additional fields wo breaking backward compatibility for tools parsing json output of nim --dump

All 6 comments

counter proposal

human readable output should not be used for machine consumption . It's meant for ease of read, not ease of parsing, and is subject to backward incompatible changes.

instead of unifying tool --version, we should unify on tool --dump which dumps json, like nim dump already does, eg:

nim dump --dump.format:json . # dump all as json
nim dump --dump.format:json .| jq .lib_paths # just show 1 key (requires jq)
nim --dump # (easy PR away, avoids running cfg/nims files when no filename specified)
nim --dump --dump.key:lib_paths # (easy PR away, avoids jq)

This is the analog of git's plumbing mode (for machine consumption) vs porcelain mode (for human consumption).

  • git hash should indicate whether it's dirty or not, as done in some other tools:
git hash: c0dbcffca643ac79e0c03c9509e92f5841b38a94
=>
git hash: c0dbcffca643ac79e0c03c9509e92f5841b38a94 # git status was clean
git hash: c0dbcffca643ac79e0c03c9509e92f5841b38a94-dirty # git status was not clean

this only affects locally built nim, and helps distinguish whether the hash indicates a reproducible state or not.

for json dump output, dirty bit could be a separate bool field in json output.

rationale

a serialization format like json (or something with a schema, eg protobuf etc) is universal, trivial to parse, and more importantly json output can be augmented with additional fields wo breaking backward compatibility for tools parsing json output of nim --dump

Not a Counter.
Why not both, improve both, the point is to improve and make use of otherwise dead code.

About copyright - AFAIK it doesn't really matter if you don't update the end year, copyright will still hold.

Why not both, improve both, the point is to improve and make use of otherwise dead code.

I mean, we can improve the human readable tool --version but this should not be for the goal of consumption by some tool, it's counter-productive, hinders addition of tool specific version info in human readable message etc. Really, json is what should be used for this task, hence tool --dump.

We can make sure that a common subset of fields are used for json (eg by using a standard library module std/dumputils) to avoid code duplication eg:

module std/dumputils
import std/json

type DumpData* = ref object of RootObj # inheritable for tools
  githash*: string
  gitdirty*: bool
  compileDate*: Time # or unix time, TBD
  semver*: string

proc setDefaults(a: DumpData) =
  a.githash = getGitHash()
  a.gitdirty = getGitDirty()
  ...

usage in some tool:

# module sometool.nim (eg nimpretty)
import std/dumputils
type DumpDataNimPretty* = ref object of DumpData
  custom: string # additional specific fields

getDump(): string =
  let a = DumpData()
  a.setDefaults
  a.custom = "bar"
  return $(%*a)

consumption in some tool:

# module someothertool.nim
import std/dumputils
let (output, exitCode) = execCmdEx("nimpretty --dump")
doAssert exitCode != 0
let data = output.parse(DumpData) # or `import nimpretty_types` and output.parse(DumpDataNimPretty)
echo data.githash ...

Any comments on?:

Alternative Solution
Just assume that all Tools that come with Nim just follow the same Version as Nim itself.

:thinking:

Just assume that all Tools that come with Nim just follow the same Version as Nim itself.

2 versions are needed for these: the nim version (since they share code) and their own version (which can introduce independent breaking changes/new features on their own schedule independently of nim's release schedule), so u can have, in the tool --dump json:

nimversion: 1.1
vesion: 0.8
Was this page helpful?
0 / 5 - 0 ratings