Skip to content

Commit

Permalink
Merge pull request #3558 from csordasmarton/fix_json_format_of_versio…
Browse files Browse the repository at this point in the history
…n_subcommand

[cli] Fix JSON format of `CodeChecker version` subcommand
  • Loading branch information
bruntib authored Jan 21, 2022
2 parents a0d262b + a45167c commit 11e5d66
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 77 deletions.
66 changes: 40 additions & 26 deletions analyzer/codechecker_analyzer/cmd/analyzer_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
"""
Defines a subcommand for CodeChecker which prints version information.
"""


import argparse
import json

from typing import Dict, List, Tuple
from codechecker_analyzer import analyzer_context

from codechecker_report_converter import twodim
Expand All @@ -21,6 +20,44 @@
from codechecker_common.output import USER_FORMATS


LOG = logger.get_logger('system')


class Version:
def __init__(self):
context = analyzer_context.get_context()

self.version = context.version
self.build_date = context.package_build_date
self.git_hash = context.package_git_hash
self.git_tag = context.package_git_tag

def to_dict(self) -> Dict[str, str]:
""" Get version information in dictionary format. """
return {
"base_package_version": self.version,
"package_build_date": self.build_date,
"git_commit": self.git_hash,
"git_tag": self.git_tag}

def to_list(self) -> List[Tuple[str, str]]:
""" Get version information in list format. """
return [
("Base package version", self.version),
("Package build date", self.build_date),
("Git commit ID (hash)", self.git_hash),
("Git tag information", self.git_tag)]

def print(self, output_format: str):
""" Print analyzer version information in the given format. """
if output_format == "json":
print(json.dumps(self.to_dict()))
else:
LOG.info("CodeChecker analyzer version:")
print(twodim.to_str(
output_format, ["Kind", "Version"], self.to_list()))


def get_argparser_ctor_args():
"""
This method returns a dict containing the kwargs for constructing an
Expand Down Expand Up @@ -58,29 +95,6 @@ def add_arguments_to_parser(parser):
parser.set_defaults(func=main)


def print_version(output_format=None):
"""
Print analyzer version information in the given format.
"""
context = analyzer_context.get_context()

rows = [
("Base package version", context.version),
("Package build date", context.package_build_date),
("Git commit ID (hash)", context.package_git_hash),
("Git tag information", context.package_git_tag)
]

if output_format == "json":
# Use a special JSON format here, instead of
# [ {"kind": "something", "version": "0.0.0"}, {"kind": "foo", ... } ]
# do
# { "something": "0.0.0", "foo": ... }
print(json.dumps(dict(rows)))
else:
print(twodim.to_str(output_format, ["Kind", "Version"], rows))


def main(args):
"""
Get and print the version information from the version config
Expand All @@ -94,4 +108,4 @@ def main(args):

logger.setup_logger(args.verbose if 'verbose' in args else None, stream)

print_version(args.output_format)
Version().print(args.output_format)
42 changes: 26 additions & 16 deletions codechecker_common/cmd/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
Defines a subcommand for CodeChecker which prints version information.
"""


import argparse
import json

from codechecker_common import logger
from codechecker_common.output import USER_FORMATS


LOG = logger.get_logger('system')


def get_argparser_ctor_args():
"""
This method returns a dict containing the kwargs for constructing an
Expand Down Expand Up @@ -61,25 +64,32 @@ def main(args):

output_format = args.output_format

has_analyzer_version = False
# Get analyzer version information if the module is available.
analyzer_version = None
try:
from codechecker_analyzer.cmd import analyzer_version
has_analyzer_version = True

# Print analyzer version information.
print("CodeChecker analyzer version:")
analyzer_version.print_version(output_format)
from codechecker_analyzer.cmd.analyzer_version import Version
analyzer_version = Version()
except Exception:
pass

# Get web version information if the module is available.
web_version = None
try:
from codechecker_web.cmd import web_version

if has_analyzer_version:
print() # Print a new line to separate version information.

# Print web server version information.
print("CodeChecker web version:")
web_version.print_version(output_format)
from codechecker_web.cmd.web_version import Version
web_version = Version()
except Exception:
pass

# Print the version information.
if output_format == "json":
print(json.dumps({
"analyzer":
analyzer_version.to_dict() if analyzer_version else None,
"web": web_version.to_dict() if web_version else None}))
else:
if analyzer_version:
analyzer_version.print(output_format)
print()

if web_version:
web_version.print(output_format)
44 changes: 44 additions & 0 deletions docs/web/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ Table of Contents
* [`login` (Authenticate to the server)](#cmd-login)
* [`export` (Export comments and review statuses from CodeChecker)](#cmd-export)
* [`import` (Import comments and review statuses into CodeChecker)](#cmd-import)
* [`version`](#version)
* [JSON format](#json-format)
* [Debugging CodeChecker](#debug)

# CodeChecker <a name="codechecker"></a>
Expand Down Expand Up @@ -1679,6 +1681,7 @@ common arguments:
--verbose {info,debug_analyzer,debug}
Set verbosity level.
```
</details>

### Authenticate to the server (`login`) <a name="cmd-login"></a>
<details>
Expand Down Expand Up @@ -1768,6 +1771,47 @@ optional arguments:
Import findings from the json file into the database.
```
## `version`
### JSON format
The JSON output format looks like this:
```json
{
"analyzer": {
"base_package_version": "6.19.0",
"package_build_date": "2021-12-15T16:07",
"git_commit": "ed16b5d58f75002b465ea0944be0abf071f0b958",
"git_tag": "6.19"
},
"web": {
"base_package_version": "6.19.0",
"package_build_date": "2021-12-15T16:07",
"git_commit": "ed16b5d58f75002b465ea0944be0abf071f0b958",
"git_tag": "6.19",
"server_api_version": [
"6.47"
],
"client_api_version": "6.47"
}
}
```
In JSON output we have two main sections:
- `analyzer` (null | object): Analyzer version information if it's available.
- `base_package_version` (string): Base package version in
`<major>.<minor>.<revision>` format.
- `package_build_date` (string): Date time when the package was built.
- `git_commit` (null | string): Git commit ID (hash).
- `git_tag` (null | string): Git tag information.
- `web` (null | object): Web version information if it's available.
- `base_package_version` (string): Base package version in
`<major>.<minor>.<revision>` format.
- `package_build_date` (string): Date time when the package was built.
- `git_commit` (null | string): Git commit ID (hash).
- `git_tag` (null | string): Git tag information.
- `server_api_version` (list[string]): Server supported Thrift API version.
- `client_api_version` (str): Client Thrift API version.
# Debugging CodeChecker <a name="debug"></a>
To change the log levels check out the [logging](../logging.md) documentation.
86 changes: 51 additions & 35 deletions web/codechecker_web/cmd/web_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import argparse
import json

from typing import Dict, List, Tuple

from codechecker_report_converter import twodim

from codechecker_common import logger
Expand All @@ -21,6 +23,54 @@
from codechecker_web.shared import webserver_context, version


LOG = logger.get_logger('system')


class Version:
def __init__(self):
context = webserver_context.get_context()

self.server_versions = [
f'{major}.{minor}'
for major, minor in version.SUPPORTED_VERSIONS.items()]

self.version = context.version
self.build_date = context.package_build_date
self.git_hash = context.package_git_hash
self.git_tag = context.package_git_tag
self.client_api = version.CLIENT_API

def to_dict(self) -> Dict[str, str]:
""" Get version information in dictionary format. """
return {
"base_package_version": self.version,
"package_build_date": self.build_date,
"git_commit": self.git_hash,
"git_tag": self.git_tag,
"server_api_version": self.server_versions,
"client_api_version": self.client_api}

def to_list(self) -> List[Tuple[str, str]]:
""" Get version information in list format. """
server_versions = ', '.join(self.server_versions)
return [
("Base package version", self.version),
("Package build date", self.build_date),
("Git commit ID (hash)", self.git_hash),
("Git tag information", self.git_tag),
("Server supported Thrift API version", server_versions),
("Client Thrift API version", self.client_api)]

def print(self, output_format: str):
""" Print web server version information in the given format. """
if output_format == "json":
print(json.dumps(self.to_dict()))
else:
LOG.info("CodeChecker web version:")
print(twodim.to_str(
output_format, ["Kind", "Version"], self.to_list()))


def get_argparser_ctor_args():
"""
This method returns a dict containing the kwargs for constructing an
Expand Down Expand Up @@ -58,40 +108,6 @@ def add_arguments_to_parser(parser):
parser.set_defaults(func=main)


def print_version(output_format=None):
"""
Print web server version information in the given format.
"""
context = webserver_context.get_context()

server_versions = ['{0}.{1}'.format(major, minor) for
major, minor in
version.SUPPORTED_VERSIONS.items()]

if output_format != 'json':
server_versions = ', '.join(server_versions)

rows = [
("Base package version", context.version),
("Package build date", context.package_build_date),
("Git commit ID (hash)", context.package_git_hash),
("Git tag information", context.package_git_tag),
("Server supported API (Thrift)", server_versions),
("Client API (Thrift)", version.CLIENT_API)
]

if output_format != "json":
print(twodim.to_str(output_format,
["Kind", "Version"],
rows))
elif output_format == "json":
# Use a special JSON format here, instead of
# [ {"kind": "something", "version": "0.0.0"}, {"kind": "foo", ... } ]
# do
# { "something": "0.0.0", "foo": ... }
print(json.dumps(dict(rows)))


def main(args):
"""
Get and print the version information from the version config
Expand All @@ -105,4 +121,4 @@ def main(args):

logger.setup_logger(args.verbose if 'verbose' in args else None, stream)

print_version(args.output_format)
Version().print(args.output_format)

0 comments on commit 11e5d66

Please sign in to comment.