指摘とメトリック API の例

これらの例は Python で記述されていますが、この言語の深い知識がなくても理解できるほど簡単なはずです。

以下の例はすべて、<server_install>/samples/demosthenes にある Klocwork サーバー パッケージでインストールされる C/C++ サンプル プロジェクト、demosthenes を使用しています。demosthenes サンプルプロジェクトは、Klocwork サーバーパッケージ全体がインストールされている場合にのみ使用できます。それは、Validate サーバーパッケージには同梱されていません。サンプルプロジェクトの設定方法については、そのディレクトリの README ファイルを参照してください。

サンプルプロジェクトまたは自分のプロジェクトで、サンプルスクリプトを試すことができます。自分のプロジェクトで使用する場合は、projectの値を変更する必要があります。また場合によっては、hostの値を localhost から自分の Klocwork サーバー ホストに変更する必要があります。

リクエストパラメータの詳細情報は以下をご覧ください。http(s)://<klocwork_server_host>:<klocwork_server_port>/review/api.

以下のほとんどの例では、プロジェクトリストの印刷を除いて、プロジェクトフィールドにフルパスを含めることでストリームを指定できます。例: project = "myProj/myStream1/subVariant"

この例でのエラー処理について

curl で Web API を使用して呼び出しが行われると、発生するすべてのエラーが自動的にコンソールに表示されます。このトピックの Python の例では単純なエラー処理について説明していることに注意してください。

コピー
builds = report(url, project, user, action)
print("Existing builds:")
for build in builds: 
    print(build)

独自の Python スクリプトでより適切にエラーを処理するには、try ブロックを使用します。

コピー
try
    builds = report(url, project, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Existing builds:")
    for build in builds: 
        print(build)

次の例について

以下の例で使用するこのモジュール (kwutil) では、システムからの ltokens の読み取りを扱います。読みやすいように別々のモジュールになっています。以下のコードを注意してコピーして貼り付け、kwutil モジュールを作成してください。

コピー
import os.path


def get_token(host, port, user): 
    ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken"))
    ltoken_file = open(ltoken, 'r')
    for r in ltoken_file: 
        rd = r.strip().split(';')
        if rd[0] == host and rd[1] == str(port) and rd[2] == user: 
            ltoken_file.close()
            return rd[3]
    ltoken_file.close()

例: 重大指摘すべての検索

このサンプル スクリプトは、Demosthenes サンプル プロジェクトの最新ビルドに含まれている重大な指摘 (重要度が 1、2、3) すべてを検索します。

コピー
import getpass
import json
import time
import urllib.parse
import urllib.request

import kwutil


class Issue(object): 
    def __init__(self, attrs):
        self.id = attrs["id"]
        self.message = attrs["message"]
        self.file = attrs["file"]
        self.method = attrs["method"]
        self.code = attrs["code"]
        self.severity = attrs["severity"]
        self.severityCode = attrs["severityCode"]
        self.supportLevel = attrs["supportLevel"]
        self.supportLevelCode = attrs["supportLevelCode"]
        self.state = attrs["state"]
        self.status = attrs["status"]
        self.taxonomyName = attrs["taxonomyName"]
        self.url = attrs["url"]
        self.created = time.ctime(attrs["dateOriginated"] / 1000)


    def __str__(self):
        return "[%d] %s\n\t%s | %s\n\tCode %s | Severity: %s(%d) | Support Level: %s(%d) | State: %s | Status: %s | Taxonomy: %s | Created: %s\n\t%s" % (
            self.id, self.message, self.file, self.method, self.code, self.severity, self.severityCode, self.supportLevel,
            self.supportLevelCode, self.state,
            self.status, self.taxonomyName, self.created, self.url
        )


def from_json(json_object): 
    if 'id' in json_object: 
        return Issue(json_object)
    return json_object


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
url = "http://%s:%d/review/api" % (host, port)
values = {"project": project, "user": user, "action": "search"}

login_token = kwutil.get_token(host, port, user)
if login_token is not None
    values["ltoken"] = login_token

values["query"] = "severity:1-3"
data = urllib.parse.urlencode(values)
data = data.encode('utf-8')
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
for record in response: 
    print(json.loads(record, object_hook=from_json))

例: 検出された指摘のレポート

この例は、検出された指摘をコンポーネント別、ステート別にグループ化した分散を示しています。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Key(object): 
    def __init__(self, attrs): 
        self.id = attrs["id"]
        self.name = attrs["name"]

    def __str__(self): 
        return "%s (%d)" % (self.name, self.id)


class Report(object): 
    def __init__(self, attrs): 
        self.rows = attrs["rows"]
        self.columns = attrs["columns"]
        self.data = attrs["data"]

    def __str__(self): 
        result = ""
        maxRowName = 0
        for r in self.rows: 
            maxRowName = max(len(str(r)), maxRowName)
        maxRowName += 1
        header = ' ' * maxRowName
        colPosition = []
        for c in self.columns: 
            colPosition.append(len(header) + len(str(r)))
            header += str(c) + ' '
        result += header + '\n'
        for x in range(len(self.rows)): 
            rHead = ('%-' + str(maxRowName) + 's') % str(self.rows[x])
            for y in range(len(self.columns)): 
                rHead += ('%' + str(len(str(self.columns[y]))) + 's') % str(self.data[x][y]) + ' '
            result += rHead + '\n'
        return result


def from_json(json_object): 
    if 'rows' in json_object: 
        return Report(json_object)
    if 'id' in json_object: 
        return Key(json_object)
    return json_object


def report(url, project, user, x=None, y=None, view=None, xDrilldown=-1, yDrilldown=-1): 
    values = {"project": project, "user": user, "action": "report"}
    login_token = kwutil.get_token(host, port, user)
    if x is not None
        values["x"] = x
    if y is not None
        values["y"] = y
    if login_token is not None
        values["ltoken"] = login_token
    if view is not None
        values["view"] = view
    if xDrilldown != -1
        values["xDrilldown"] = xDrilldown
    if yDrilldown != -1
        values["yDrilldown"] = yDrilldown
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    for record in response: 
        return json.loads(record, object_hook=from_json)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
url = "http://%s:%d/review/api" % (host, port)

try
    reports = report(url, project, user, "Component", "State")
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print(reports)

例: 指摘情報の検索

この例では、指定された指摘 ID に関する詳細を検索する方法を示しています。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Details(object): 
    def __init__(self, attrs): 
        self.id = attrs["id"]
        self.code = attrs["code"]
        self.name = attrs["name"]
        self.location = attrs["location"]
        self.build = attrs["build"]
        self.severity = attrs["severity"]
        self.supportLevel = attrs["supportLevel"]
        self.owner = attrs["owner"]
        self.state = attrs["state"]
        self.status = attrs["status"]
        if "history" in attrs: 
            self.history = attrs["history"]
        else
            self.history = None
        if "xSync" in attrs: 
            self.xsync = attrs["xsync"]
        else
            self.xsync = None


    def __str__(self): 
        result = "Id:%s, Code:%s, Name:%s, Location:%s, Build:%s, Severity:%s, Support Level%s, Owner:%s, State:%s, Status:%s, History:%s" % (
            self.id, self.code, self.name, self.location, self.build, self.severity, self.supportLevel, self.owner,
            self.state,
            self.status, self.history)
        if self.xsync is not None
            result = result + ", XSyncInfo:%s" % self.xsync
        return result


def from_json(json_object): 
    # print json_object
    return Details(json_object)


def report(url, user, action, project, id, xsync=None): 
    values = {"user": user, "action": action, "project": project, "id": id}
    if xsync is not None
        values['include_xsync'] = xsync
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        # print "R:",record
        result.append(from_json(json.loads(record)))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
action = "issue_details"
url = "http://%s:%d/review/api" % (host, port)
project = "demosthenes"
id = "4"
xsync = "false"

try
    issue_details = report(url, user, action, project, id, xsync)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Issue Details:")
    for details in issue_details: 
        print(details)

例: CI 指摘情報の検索

この例では、指定された CI 指摘 ID に関する詳細を検索する方法を示します。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Details(object): 
    def __init__(self, attrs): 
        self.id = attrs["id"]
        self.code = attrs["code"]
        self.name = attrs["name"]
        self.location = attrs["location"]
        self.build = attrs["build"]
        self.severity = attrs["severity"]
        self.supportLevel = attrs["supportLevel"]
        self.owner = attrs["owner"]
        self.status = attrs["status"]
        if "history" in attrs: 
            self.history = attrs["history"]
        else
            self.history = None
        if "xSync" in attrs: 
            self.xsync = attrs["xsync"]
        else
            self.xsync = None


    def __str__(self): 
        result = "Id:%s, Code:%s, Name:%s, Location:%s, Build:%s, Severity:%s, Support Level%s, Owner:%s, State:%s, Status:%s, History:%s" % (
            self.id, self.code, self.name, self.location, self.build, self.severity, self.supportLevel, self.owner,
            self.state,
            self.status, self.history)
        if self.xsync is not None
            result = result + ", XSyncInfo:%s" % self.xsync
        return result


def from_json(json_object): 
    # print json_object
    return Details(json_object)


def report(url, user, action, project, id, ci_build_name): 
    values = {"user": user, "action": action, "project": project, "id": id, "ci_build_name": ci_build_name}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        # print "R:",record
        result.append(from_json(json.loads(record)))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
action = "ci_issue_details"
url = "http://%s:%d/review/api" % (host, port)
project = "demosthenes"
id = "1"
ci_build_name = "ci_build_1"

try
    ci_issue_details = report(url, user, action, project, id, ci_build_name)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Issue Details:")
    for details in ci_issue_details: 
        print(details)

例: 指摘ステータスの更新

この例では、特定の指摘の指摘ステータス、コメント、オーナー、バグ追跡システム ID の変更方法を説明しています。

バグ追跡システム ID を指定すると、他のすべての指摘ステータスの値は無視されます。
コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Status(object): 
    def __init__(self, attrs): 
        self.status_message = attrs["status_message"]

    def __str__(self): 
        result = "Status message:%s" % self.status_message
        return result


def from_json(json_object): 
    return Status(json_object)


def update_status(url, user, project, ids, status=None, comment=None, owner=None, bug_tracker_id=None): 
    values = {'action': 'update_status', 'project': project, 'user': user, 'ids': ids}
    if status is not None
        values['status'] = status
    if comment is not None
        values['comment'] = comment
    if owner is not None
        values['owner'] = owner
    if bug_tracker_id is not None
        values['bug_tracker_id'] = bug_tracker_id
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        result.append(json.loads(record, object_hook=from_json))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
url = "http://%s:%d/review/api" % (host, port)
project = "demosthenes"
id = "1"
status = "Fix"
comment = "Making a status change"
owner = "jsmith"

try
    status_messages = update_status(url, user, project, id, status, comment, owner)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Update Status:")
    for message in status_messages: 
        print(message)

例: プロジェクトリストの表示

この例では、プロジェクト リストの表示方法を示します。

デフォルトでは、クエリはベースプロジェクトのみのリストを返します。include_streams フラグに true の値 (デフォルトは false) を指定することで、クエリにすべてのベースプロジェクトとストリームを表示させることもできます。たとえば、次の値でクエリを含めるようにします。

  • action=projects

  • user=someone

  • include_streams=true

...次の集計結果が生成されて返されます:

{"id":"project1","name":"project1","creator":"someone","description":""}

{"id":"project1_sub1","name":"project1/sub1","creator":"someone","description":"","tags":["s"]}

{"id":"project1_sub2","name":"project1/sub1/sub2","creator":"someone","description":""}

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class View(object): 
    def __init__(self, attrs): 
        self.name = attrs["name"]

    def __str__(self): 
        result = "%s" % self.name
        return result


def from_json(json_object): 
    return View(json_object)


def report(url, user, action): 
    values = {"user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        result.append(json.loads(record, object_hook=from_json))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
action = "projects"
url = "http://%s:%d/review/api" % (host, port)

try
    projects = report(url, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Existing projects:")
    for project in projects: 
        print(project)

例: プロジェクトの更新

この例では、指定したプロジェクトの名前および説明の更新方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def update_project(url, name, user, action, description, new_name): 
    values = {"name": name, "user": user, "action": action, "description": description, "new_name": new_name}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
name = "demosthenes"
action = "update_project"
description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
new_name = "demosthenes2"
url = "http://%s:%d/review/api" % (host, port)

try
    update_project(url, name, user, action, description, new_name)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Project updated!")

また、このアクションを使用すると、ビルドの自動削除をオンにし、しきい値パラメーターを使用して保持する数を設定できます。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def update_project(url, name, user, action, auto_delete_builds, auto_delete_threshold): 
    values = {"name": name, "user": user, "action": action, "auto_delete_builds": auto_delete_builds,
              "auto_delete_threshold": auto_delete_threshold}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
name = "demosthenes"
action = "update_project"
auto_delete_builds = "true"
auto_delete_threshold = "30"
url = "http://%s:%d/review/api" % (host, port)

try
    update_project(url, name, user, action, auto_delete_builds, auto_delete_threshold)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Project updated!")

例: プロジェクトの作成

この例では、新しいプロジェクトの作成方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def create_project(url, name, user, action): 
    values = {"name": name, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
name = "demosthenes"
action = "create_project"
url = "http://%s:%d/review/api" % (host, port)

try
    create_project(url, name, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Project created!")

例: プロジェクトの削除

この例では、指定されたプロジェクトの削除方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def delete_project(url, name, force, user, action): 
    values = {"name": name, "force": force, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
name = "demosthenes"
force = True
action = "delete_project"
url = "http://%s:%d/review/api" % (host, port)

try
    delete_project(url, name, force, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Project and its streams deleted!")

例: プロジェクト構成レポートの生成

この例では、指定したプロジェクトの構成レポートの生成方法を示します。このレポートは、作成日、Klocwork のバージョン、基準となるコードメトリックなど、プロジェクトに関する情報を表示します。
コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Config(object): 
    def __init__(self, attrs): 
        self.build = attrs["build"]
        self.creationDate = attrs["creationDate"]
        self.version = attrs["version"]
        self.numberOfFiles = attrs["numberOfFiles"]
        self.cFilesAnalyzed = attrs["cFilesAnalyzed"]
        self.systemFilesAnalyzed = attrs["systemFilesAnalyzed"]
        self.linesOfCode = attrs["linesOfCode"]
        self.linesOfComments = attrs["linesOfComments"]
        self.numberOfEntities = attrs["numberOfEntities"]
        self.numberOfFunctions = attrs["numberOfFunctions"]
        self.numberOfClasses = attrs["numberOfClasses"]
        self.taxonomies = attrs["taxonomies"]

    def __str__(self): 
        result = "Build:%s, Creation Date:%s, Version:%s, Number of Files:%s, C Files Analyzed:%s, System Files Analyzed:%s, Lines of Code:%s, Lines of Comments:%s.Number of Entities:%s, Number of Functions:%s, Number of Classes:%s, Taxonomies:%s" % (
            self.build, self.creationDate, self.version, self.numberOfFiles, self.cFilesAnalyzed,
            self.systemFilesAnalyzed,
            self.linesOfCode, self.linesOfComments, self.numberOfEntities, self.numberOfFunctions, self.numberOfClasses,
            self.taxonomies)
        return result


def from_json(json_object): 
    return Config(json_object)


def report(url, user, action, project, build=None): 
    values = {"user": user, "action": action, "project": project}
    if build is not None
        values['build'] = build
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = json.loads(response.read(), object_hook=from_json)
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
action = "project_configuration"
url = "http://%s:%d/review/api" % (host, port)
project = "demosthenes"
build = "build_1"

try
    result = report(url, user, action, project, build)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Project Configuration:")
    print(result)

例: ビューリストの表示

この例では、ビューリストの表示方法を示します。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class View(object): 
    def __init__(self, attrs): 
        self.name = attrs["name"]
        self.query = attrs["query"]
        self.creator = attrs["creator"]
        if "tags" in attrs: 
            self.tags = attrs["tags"]
        else
            self.tags = ""
        self.is_public = attrs["is_public"]

    def __str__(self): 
        result = "Name:%s (Query:%s, Creator:%s, Public:%s) Tags: [" % (
            self.name, self.query, self.creator, self.is_public)
        for x in range(len(self.tags)): 
            if not x: 
                result = result + self.tags[x]
            else
                result = result + ',' + self.tags[x]
        result += ']'
        return result


def from_json(json_object): 
    return View(json_object)


def report(url, project, user): 
    values = {"project": project, "user": user, "action": "views"}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        result.append(json.loads(record, object_hook=from_json))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
url = "http://%s:%d/review/api" % (host, port)

try
    views = report(url, project, user)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    for view in views: 
        print(view)

例: ビューの作成

この例では、ビューの作成方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def create_view(url, user, project, name, action, query, tags): 
    values = {"project": project, "user": user, "name": name, "action": action, "query": query, "tags": tags}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
name = "Sample View"
action = "create_view"
query = "severity:1-3"
tags = "c,security"
url = "http://%s:%d/review/api" % (host, port)
try
    create_view(url, user, project, name, action, query, tags)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("View created!")

例: ビューの更新

この例では、ビューの更新方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def update_view(url, user, project, name, newname, action, query, is_public, tags): 
    values = {"project": project,
              "user": user,
              "name": name,
              "new_name": newname,
              "action": action,
              "query": query,
              "is_public": is_public,
              "tags": tags}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
name = "Sample View"
newname = "Updated Sample View"
action = "update_view"
query = "severity:1"
tags = "c,security,important"
is_public = "true"
url = "http://%s:%d/review/api" % (host, port)
try
    update_view(url, user, project, name, newname, action, query, is_public, tags)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("View updated!")

例: ビューの削除

この例では、ビューの削除方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def delete_view(url, user, name, project, action): 
    values = {"project": project, "name": name, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
name = "Sample View"
project = "demosthenes"
action = "delete_view"
url = "http://%s:%d/review/api" % (host, port)
try
    delete_view(url, user, name, project, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("View deleted!")

例: モジュールリストの表示

この例では、モジュール リストの表示方法を示します。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Module(object): 
    def __init__(self, attrs): 
        self.name = attrs["name"]

    def __str__(self): 
        result = "%s" % (self.name)
        return result


def from_json(json_object): 
    return Module(json_object)


def list_modules(url, project, user, action): 
    values = {"project": project, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        result.append(json.loads(record, object_hook=from_json))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
action = "modules"
url = "http://%s:%d/review/api" % (host, port)

try
    modules = list_modules(url, project, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Existing modules:")
    for module in modules: 
        print(module)

例: モジュールの作成

この例では、モジュールの作成方法を示します。

アクセス制御メソッドが設定されている場合、モジュールを作成して編集するには、プロジェクト管理者の役割または 'モジュールの管理' パーミッションを持つ必要があります。モジュールでのアクセス パーミッションを追加または変更するには、'役割の割り当て' パーミッションが必要です (デフォルトでプロジェクト管理者が持つ)。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def create_module(url, user, project, name, action, allow_all, paths): 
    values = {"project": project, "user": user, "name": name, "action": action, "allow_all": allow_all, "paths": paths}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
name = "mymodule"
action = "create_module"
allow_all = "true"
paths = "**/test/*"
url = "http://%s:%d/review/api" % (host, port)
try
    create_module(url, user, project, name, action, allow_all, paths)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Module created!")

例: モジュールの更新

この例では、モジュールの更新方法を示します。

アクセス制御メソッドが設定されている場合、モジュールを作成して編集するには、プロジェクト管理者の役割または 'モジュールの管理' パーミッションを持つ必要があります。モジュールでのアクセス パーミッションを追加または変更するには、'役割の割り当て' パーミッションが必要です (デフォルトでプロジェクト管理者が持つ)。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def update_module(url, user, project, name, new_name, action, allow_all): 
    values = {"project": project, "user": user, "name": name, "new_name": new_name, "action": action,
              "allow_all": allow_all}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
name = "mymodule"
new_name = "mymodule2"
action = "update_module"
allow_all = "false"
url = "http://%s:%d/review/api" % (host, port)
try
    update_module(url, user, project, name, new_name, action, allow_all)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Module updated!")

例: モジュールの削除

この例では、モジュールの削除方法を示します。

アクセス制御メソッドが設定されている場合、モジュールを作成して編集するには、プロジェクト管理者の役割または 'モジュールの管理' パーミッションを持つ必要があります。モジュールでのアクセス パーミッションを追加または変更するには、'役割の割り当て' パーミッションが必要です (デフォルトでプロジェクト管理者が持つ)。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def delete_module(url, user, name, project, action): 
    values = {"project": project, "name": name, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
name = "mymodule"
project = "demosthenes"
action = "delete_module"
url = "http://%s:%d/review/api" % (host, port)
try
    delete_module(url, user, name, project, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Module deleted!")

例: ビルドリストの表示

この例では、ビルド リストの表示方法を示します。ビルドの管理の詳細については、統合ビルドの管理を参照してください。

コピー
import getpass
import json
import time
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Build(object): 
    def __init__(self, attrs): 
        self.id = attrs["id"]  # build id
        self.name = attrs["name"]  # build name
        self.date = time.ctime(attrs["date"] / 1000)  # build date
        self.keepit = attrs["keepit"]  # sticky flag

    def __str__(self): 
        result = "%s: %s" % (self.name, self.date)
        return result


def from_json(json_object): 
    return Build(json_object)


def report(url, project, user, action): 
    values = {"project": project, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        result.append(json.loads(record, object_hook=from_json))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
action = "builds"
url = "http://%s:%d/review/api" % (host, port)

try
    builds = report(url, project, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Existing builds:")
    for build in builds: 
        print(build)

例: 保存するビルドの指定

この例では、毎秒ビルドが自動削除機能によって削除されないことを示します。

このアクションでは、'keepit' オプションを指定することによって特定のビルドを保持するかどうかを指定することもできます。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Build(object): 
    def __init__(self, attrs): 
        self.id = attrs["id"]
        self.name = attrs["name"]
        self.date = attrs["date"]

    def __str__(self): 
        return "Id: %s Name:%s Date:%i" % (self.id, self.name, self.date)


def from_json(json_object): 
    return Build(json_object)


def keepit(build_name, login_token): 
    print("retain " + build_name)
    values = {"project": project, "user": user, "action": "update_build", "name": build_name, "keepit": "true"}
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


def retain(url, project, user): 
    values = {"project": project, "user": user, "action": "builds"}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)

    i = 0
    for record in response: 
        build = json.loads(record, object_hook=from_json)

        i += 1
        if not i % 2
            keepit(build.name, login_token)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
url = "http://%s:%d/review/api" % (host, port)

retain(url, project, user)

例: ビルドの削除

この例では、ビルドの削除方法を示します。ビルドの管理の詳細については、統合ビルドの管理を参照してください。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def delete_build(url, user, project, build, action): 
    values = {"project": project, "name": build, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
build = "demosthenes_3"
action = "delete_build"
url = "http://%s:%d/review/api" % (host, port)
try
    delete_build(url, user, project, build, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Build deleted!")

例: CI ビルドの作成

この例では、CI ビルドの作成方法を示します。

コピー
import getpass
import json
import time
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class CiBuild(object): 
    def __init__(self, attrs): 
        self.id = attrs["id"]  # build id
        self.name = attrs["name"]  # build name
        self.date = time.ctime(attrs["date"] / 1000)  # build date

    def __str__(self): 
        result = "%s: %s" % (self.name, self.date)
        return result


def from_json(json_object): 
    return CiBuild(json_object)


def report(url, project, user, action): 
    values = {"project": project, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        result.append(json.loads(record, object_hook=from_json))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
action = "ci_builds"
url = "http://%s:%d/review/api" % (host, port)

try
    ci_builds = report(url, project, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Existing Ci Builds:")
    for ci_build in ci_builds: 
        print(ci_build)

例: CI ビルドの更新

この例では、CI ビルドの更新方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def rename(url, user, action, project, old_ci_build_name, new_ci_build_name): 
    values = {"user": user, "action": action, "project": project, "name": old_ci_build_name, "new_name": new_ci_build_name}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
url = "http://%s:%d/review/api" % (host, port)
action = "update_ci_build"
old_ci_build_name = "ci_build_1"
new_ci_build_name = "win-ci_build_1"


try
    rename(url, user, action, project, old_ci_build_name, new_ci_build_name)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Ci Build successfully renamed")

例: CI ビルドの削除

この例では、CI ビルドの削除方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def delete_build(url, user, project, build, action): 
    values = {"project": project, "name": build, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
build = "ci_build_1"
action = "delete_ci_build"
url = "http://%s:%d/review/api" % (host, port)
try
    delete_build(url, user, project, build, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Build deleted!")

例: 有効化されたチェッカーのリストの表示

この例では、有効化されたチェッカーのリストの表示方法を示します。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class View(object): 
    def __init__(self, attrs): 
        self.code = attrs["code"]
        self.name = attrs["name"]
        self.enabled = attrs["enabled"]
        self.severity = attrs["severity"]
        self.supportLevel = attrs["supportLevel"]

    def __str__(self): 
        result = "Code: %s\nName: %s\nEnabled: %s\nSeverity: %s\nSupport Level: %s\n" % (
            self.code, self.name, self.enabled, self.severity, self.supportLevel)
        return result


def from_json(json_object): 
    return View(json_object)


def report(url, project, user, action): 
    values = {"project": project, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        result.append(json.loads(record, object_hook=from_json))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
action = "defect_types"
taxonomy = "C and C++"
url = "http://%s:%d/review/api" % (host, port)

try
    defects = report(url, project, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Defect types:")
    for defect in defects: 
        print(defect)

例: 分類基準のリストの表示

この例では、分類基準のリストの表示方法を示します。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class View(object): 
    def __init__(self, attrs): 
        self.name = attrs["name"]
        self.is_custom = attrs["is_custom"]

    def __str__(self): 
        result = "Name: %s\nIs Custom: %s\n" % (self.name, self.is_custom)
        return result


def from_json(json_object): 
    return View(json_object)


def report(url, project, user, action): 
    values = {"project": project, "user": user, "action": action}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    result = []
    for record in response: 
        result.append(json.loads(record, object_hook=from_json))
    return result


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
action = "taxonomies"
url = "http://%s:%d/review/api" % (host, port)

try
    taxonomies = report(url, project, user, action)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Taxonomies:")
    for taxonomy in taxonomies: 
        print(taxonomy)

例: チェッカーの有効化および無効化

この例では、チェッカーの有効化および無効化の方法を示します。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def set_defect(url, project, user, action, code, enabled, severity): 
    values = {"project": project, "user": user, "action": action, "code": code, "enabled": enabled,
              "severity": severity}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
action = "update_defect_type"
code = "VOIDRET"
enabled = "True"
severity = "1"
url = "http://%s:%d/review/api" % (host, port)

try
    set_defect(url, project, user, action, code, enabled, severity)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())
else
    print("Defect type %s updated!\nEnabled: %s\nSeverity: %s" % (code, enabled, severity))

例: メトリックのレポート

次の例では、直前のビルドのプロジェクトにおける各ファイルのコメント付きおよびコメントが付いてない行の行数、実行可能ステートメント数、最大のネストレベル、および循環的複雑度メトリックをレポートします。

有効なメトリックコードのリストについては、Klocwork メトリック リファレンスを参照してください。

コピー
import getpass
import json
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class Metric(object): 
    def __init__(self, attrs): 
        self.file = attrs["filePath"]
        self.entity = attrs["entity"]
        self.tag = attrs["tag"]
        self.value = attrs["metricValue"]

    def __str__(self): 
        return "%s;%s;%d" % (self.file, self.tag, self.value)


def from_json(json_object): 
    if 'filePath' in json_object: 
        return Metric(json_object)
    return json_object


host = "localhost"
port = 8080
user = getpass.getuser()
project = "demosthenes"
url = "http://%s:%d/review/api" % (host, port)
values = {"project": project, "user": user, "action": "metrics"}

login_token = kwutil.get_token(host, port, user)
if login_token is not None
    values["ltoken"] = login_token

values["query"] = "metric:+RNOEXSTAT,+LINESCOMM,+NCNBLOC_FILE,+RMAXLEVEL,+RCYCLOMATIC"
data = urllib.parse.urlencode(values)
data = data.encode('utf-8')
req = urllib.request.Request(url, data)
try
    response = urllib.request.urlopen(req)
    for record in response: 
        print(json.loads(record, object_hook=from_json))
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())

集約された検索結果

デフォルトでは、メトリック API はファイルごとに結果を生成します。特定のクエリですべてのファイルについて集約された検索結果を生成するには、true (デフォルトは false) の値で aggregate フラグを指定します。次の例では、集約された検索結果を示します。

次の値でのクエリ:

  • action=metrics
  • user=someone
  • query=metric:+LOC_FILE
  • project=demosthenes
  • aggregate=true

...次の集計結果が生成されて返されます:

{"tag":"LOC_FILE","sum":8113.0,"min":3.0,"max":966.0,"entries":47}

aggregate フラグはデータに関連性がある場合にのみ役立ちます。つまり、メトリックの集約が可能であるか、最大値と最小値を決められる場合です。

システムファイルの検索結果からの除外

デフォルトでは、メトリック API はすべてのファイルに基づいて結果を生成します。クエリオミットシステムファイルは、値 true (デフォルトは false) で exclude_system_files フラグを指定して得ることができます。

次の値でのクエリ:

  • action=metrics
  • user=someone
  • project=demosthenes
  • aggregate=true
  • exclude_system_files=true
  • query=metric:+LOC_FILE

curl 要求の例:

curl --data "action=metrics&user=someone&project=demosthenes&exclude_system_files=true&query=metric:%2bLOC_FILE&aggregate=true" http://localhost:8080/review/api

...次の結果が生成されて返されます:

{"tag":"LOC_FILE","sum":322.0,"min":3.0,"max":68.0,"entries":13}

サーバー設定、プロジェクト、およびコード レビューのインポート

API では、コマンドラインを使用してサーバー設定、プロジェクト、またはコード レビューをインポートすることもできます。これは、次のような各方法で実行できます。

サーバー設定をインポートするには

次の例では、認証構成、パーミッション、カスタム メトリクス、レポート定義、および電子メール購読設定をインポートします。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def import_server_configuration(url, user, sourceURL, sourceAdmin, sourcePassword): 
    values = {"action": "import_server_configuration",
              "user": user,
              "sourceURL": sourceURL,
              "sourceAdmin": sourceAdmin}
    if sourcePassword is not None
        values["sourcePassword"] = sourcePassword
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()

sourceURL = "http://oldhost:8080"
sourceAdmin = "old admin user name"
sourcePassword = None

url = "http://%s:%d/review/api" % (host, port)

try
    import_server_configuration(url, user, sourceURL, sourceAdmin, sourcePassword)
    print("Imported server configuration!")
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())

プロジェクトをインポートするには

次の例では、指定されたプロジェクトについて Klocwork が収集したデータをインポートします。

コピー
import getpass
import urllib.error
import urllib.parse
import urllib.request

import kwutil


def import_project(url, user, project, sourceURL, sourceAdmin, sourcePassword): 
    values = {"action": "import_project",
              "user": user,
              "project": project,
              "sourceURL": sourceURL,
              "sourceAdmin": sourceAdmin}
    if sourcePassword is not None
        values["sourcePassword"] = sourcePassword
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


host = "localhost"
port = 8080
user = getpass.getuser()

project = "projectA"
sourceURL = "http://oldhost:8080"
sourceAdmin = "old admin user name"
sourcePassword = None

url = "http://%s:%d/review/api" % (host, port)

try
    import_project(url, user, project, sourceURL, sourceAdmin, sourcePassword)
    print("Imported project!")
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())

インポートステータスをチェックするには

この API メソッドを使用すると、サーバー設定、プロジェクト、またはコード レビューのインポートのステータスを確認できます。

コピー
import getpass
import json
import sys
import time
import urllib.error
import urllib.parse
import urllib.request

import kwutil


class ImportStatus(object): 
    def __init__(self, project, attrs): 
        self.project = project
        self.stage = attrs["stage"]
        self.progress = attrs["progress"]
        self.failed = attrs["failed"]
        self.hasWarnings = attrs["hasWarnings"]
        self.projectReady = attrs["projectReady"]
        self.complete = attrs["complete"]

    def __str__(self): 
        return "Project: %s\n\tStage: %s | Progress: %s%% | Failed: %s | Warnings: %s | Project Ready: %s | Complete: %s" % (
            self.project, self.stage, self.progress, self.failed, self.hasWarnings, self.projectReady, self.complete)


def import_status(url, user): 
    values = {"action": "import_status", "user": user}
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    response = urllib.request.urlopen(req)
    importStatus = []
    for record in response: 
        attrs = json.loads(record)
        for key in attrs.keys(): 
            importStatus.append(ImportStatus(key, attrs[key]))
    return importStatus


def import_project(url, user, project, sourceURL, sourceAdmin, sourcePassword=None, ): 
    values = {"action": "import_project",
              "user": user,
              "project": project,
              "sourceURL": sourceURL,
              "sourceAdmin": sourceAdmin}
    if sourcePassword: 
        values["sourcePassword"] = sourcePassword
    login_token = kwutil.get_token(host, port, user)
    if login_token is not None
        values["ltoken"] = login_token
    data = urllib.parse.urlencode(values)
    data = data.encode('utf-8')
    req = urllib.request.Request(url, data)
    urllib.request.urlopen(req)


def wait_for_import(url, user, project): 
    is_timeout = False
    TIME_OUT = time.time() + 60 * 20
    incomplete = [project]

    if len(incomplete) == 0
        return

    while True
        for status in import_status(url, user): 
            if status.project != project: 
                continue

            # If all operations are complete then exit the loop
            if len(incomplete) == 0
                break

            if status.project in incomplete: 
                is_timeout = time.time() > TIME_OUT

            if status.complete or status.failed: 
                print(status.stage)
                incomplete.pop(incomplete.index(status.project))
                break
            elif is_timeout: 
                print("Import of project '%s' took longer than expected."% status.project)
                print("Check if import is still progressing.")
                sys.exit(-1)

        # If all projects are complete then exit the loop
        if len(incomplete) == 0
            break

        time.sleep(10)


host = "localhost"
port = 8080
user = getpass.getuser()

url = "http://%s:%d/review/api" % (host, port)

project = "demosthenes"
sourceURL = "http://oldhost:8080"
sourceAdmin = "old admin user name"

try
    import_project(url, user, project, sourceURL, sourceAdmin)
    print("Import started")
    wait_for_import(url, user, project)
except urllib.error.HTTPError as e: 
    print("Request failed:", e.reason, ":", e.read())

Klocwork サーバーのバージョンをチェックするには

このアクションにより、Klocwork サーバーのバージョンを取得できます。このアクションのための curl コマンドの例を次に示します。
curl --data "action=version&user=myself&" http://jsmith.klocwork.com:8080/review/api
以下に、このコマンドからのサンプル出力を示します。
              1 {
              2 majorVersion: "10.1"
              3 minorVersion: "1"
              4 }

Klocwork サーバーで起動しているすべてのタスクのステータスをリストするには

このアクションにより、Klocwork サーバーで起動している各タスクのステータスをリストできます。このアクションのための curl コマンドの例を次に示します。
curl --data "action=task_status&user=myself&" http://jsmith.klocwork.com:8080/review/api