EN JP CN

指摘とメトリック API の例

指摘とメトリック API の例

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

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

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

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

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

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 urllib2.HTTPError as e:
     print "Request failed: " + e.reason + ": " + e.read()
else:
     print "Existing builds:"
     for build in builds:
         print build

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

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

import urllib, urllib2, json, sys, os.path, getpass, time

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

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.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) | 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.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"}

loginToken = getToken(host, port, user)
if loginToken is not None :
   values["ltoken"] = loginToken

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

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

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

import urllib, urllib2, json, sys, os.path, getpass

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

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"}
   loginToken = getToken(host, port, user)
   if x is not None :
      values["x"] = x
   if y is not None :
      values["y"] = y
   loginToken = getToken(host, port, user)
   if loginToken is not None :
      values["ltoken"] = loginToken
   if view is not None :
      values["view"] = view
   if xDrilldown != -1 :
      values["xDrilldown"] = xDrilldown
   if yDrilldown != -1 :
      values["yDrilldown"] = yDrilldown
   data = urllib.urlencode(values)
   req = urllib2.Request(url, data)
   response = urllib2.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)

print report(url, project, user, "Component", "State")

例:指摘情報の検索

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

import urllib, urllib2, json, sys, os.path, getpass

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

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.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, Owner:%s, State:%s, Status:%s, History:%s" % (self.id, self.code, self.name, self.location, self.build, self.severity, self.owner, self.state, self.status, self.history)
        if self.xsync != 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
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    response = urllib2.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 = "myproject"
id = "4"
xsync="false"

issue_details = report(url, user, action, project, id, xsync)
print "Issue Details:"
for details in issue_details:
    print details

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

この例では、特定の指摘の指摘ステータス、コメント、オーナー、バグ追跡システム ID の変更方法を説明しています。
注: バグ追跡システム ID を指定すると、他のすべての指摘ステータスの値は無視されます。
import urllib, urllib2, json, sys, os.path, getpass

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


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, action, 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
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    response = urllib2.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 = "update_status"
url = "http://%s:%d/review/api" % (host, port)
project = "demosthenes"
id = "1"
status = "Fix"
comment = "Making a status change"
owner = "jsmith"

status_messages = update_status(url, user, action, project, id, status, comment, owner)
print "Update Status:"
for message in status_messages:
    print message

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

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

import urllib, urllib2, json, sys, os.path, getpass

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


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}
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    response = urllib2.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)

projects = report(url, user, action)
print "Existing projects:"
for project in projects:
    print project

例:プロジェクトの更新

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

import urllib, urllib2, json, sys, os.path, getpass

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


def updateProject(url, name, user, action, description, new_name) :
    values = {"name": name, "user": user, "action": action, "description": description, "new_name": new_name}
    loginToken = getToken(host, port, user)
    if loginToken is not None :
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.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)

updateProject(url, name, user, action, description, new_name)
print "Project updated!"

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

import urllib, urllib2, json, sys, os.path, getpass

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


def updateProject(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}
    loginToken = getToken(host, port, user)
    if loginToken is not None :
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.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)

updateProject(url, name, user, action, auto_delete_builds, auto_delete_threshold)
print "Project updated!"

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

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

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


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
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    response = urllib2.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 = "project_configuration"
url = "http://%s:%d/review/api" % (host, port)
project = "demosthenes"
build = "build_1"

project_configuration = report(url, user, action, project, build)
print "Project Configuration:"
for project_config in project_configuration:
    print project_config

例:ビューリストの表示

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

import urllib, urllib2, json, sys, os.path, getpass

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


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"}
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    response = urllib2.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)

views = report(url, project, user)
for view in views:
    print view

例:ビューの作成

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

import urllib, urllib2, json, sys, os.path, getpass

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


def createView(url, user, project, name, action, query, tags):
    values = {"project": project, "user": user, "name": name, "action": action, "query": query, "tags": tags}
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.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)
createView(url, user, project, name, action, query, tags)
print "View created!"

例:ビューの更新

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

import urllib, urllib2, json, sys, os.path, getpass

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


def updateView(url, user, project, name, newname, action, query, ispublic, tags):
    values = {"project": project,
              "user": user,
              "name": name,
              "new_name": newname,
              "action": action,
              "query": query,
              "is_public": ispublic,
              "tags": tags}
    loginToken = getToken(host, port, user)
    if loginToken is not None :
      values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.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"
ispublic = "true"
url = "http://%s:%d/review/api" % (host, port)
updateView(url, user, project, name, newname, action, query, ispublic, tags)
print "View updated!"

例:ビューの削除

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

import urllib, urllib2, json, sys, os.path, getpass

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


def deleteView(url, user, name, project, action):
    values = {"project": project, "name": name, "user": user, "action": action}
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.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)
deleteView(url, user, name, project, action)
print "View deleted!"

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

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

import urllib, urllib2, json, sys, os.path, getpass

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

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 listModules(url, project, user, action) :
  values = {"project": project, "user": user, "action": action}
  loginToken = getToken(host, port, user)
  if loginToken is not None :
    values["ltoken"] = loginToken
  data = urllib.urlencode(values)
  req = urllib2.Request(url, data)
  response = urllib2.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)

modules = listModules(url, project, user, action)
print "Existing modules:"
for module in modules :
  print module

例:モジュールの作成

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

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

def createModule(url, user, project, name, action, allow_all, paths) :
  values = {"project": project, "user": user, "name": name, "action": action, "allow_all": allow_all, "paths": paths}
  loginToken = getToken(host, port, user)
  if loginToken is not None :
    values["ltoken"] = loginToken
  data = urllib.urlencode(values) 
  req = urllib2.Request(url, data)
  response = urllib2.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)
createModule(url, user, project, name, action, allow_all, paths)
print "Module created!"

例:モジュールの更新

この例では、モジュールの更新方法を示します。
注: アクセス制御メソッドが設定されている場合、モジュールを作成して編集するには、プロジェクト管理者の役割または 'モジュールの管理' パーミッションを持つ必要があります。モジュールでのアクセス パーミッションを追加または変更するには、'役割の割り当て' パーミッションが必要です (デフォルトでプロジェクト管理者が持つ)。
import urllib, urllib2, json, sys, os.path, getpass

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

def updateModule(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}
  loginToken = getToken(host, port, user)
  if loginToken is not None :
    values["ltoken"] = loginToken
  data = urllib.urlencode(values)
  req = urllib2.Request(url, data)
  response = urllib2.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)
updateModule(url, user, project, name, new_name, action, allow_all)
print "Module updated!"

例:モジュールの削除

この例では、モジュールの削除方法を示します。
注: アクセス制御メソッドが設定されている場合、モジュールを作成して編集するには、プロジェクト管理者の役割または 'モジュールの管理' パーミッションを持つ必要があります。モジュールでのアクセス パーミッションを追加または変更するには、'役割の割り当て' パーミッションが必要です (デフォルトでプロジェクト管理者が持つ)。
import urllib, urllib2, json, sys, os.path, getpass

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

def deleteModule(url, user, name, project, action) :
  values = {"project": project, "name": name, "user": user, "action": action}
  loginToken = getToken(host, port, user)
  if loginToken is not None :
    values["ltoken"] = loginToken
  data = urllib.urlencode(values)
  req = urllib2.Request(url, data)
  response = urllib2.urlopen(req)

host = "localhost"
port = 8080
user = getpass.getuser()
name = "mymodule"
project = "demosthenes"
action = "delete_module"
url = "http://%s:%d/review/api" % (host, port)
deleteModule(url, user, name, project, action)
print "Module deleted!"

例:ビルドリストの表示

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

import urllib, urllib2, json, sys, os.path, getpass, time

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


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}
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    response = urllib2.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)

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

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

この例では、毎秒ビルドが自動削除機能によって削除されないことを示します。
注: このアクションでは、'keepit' オプションを指定することによって特定のビルドを保持するかどうかを指定することもできます。
import urllib, urllib2, json, sys, os.path, getpass

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

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, loginToken):
   print "retain " + build_name
   values = {"project": project, "user": user, "action": "update_build", "name": build_name, "keepit" : "true"}
   if loginToken is not None :
      values["ltoken"] = loginToken
   data = urllib.urlencode(values)
   req = urllib2.Request(url, data)

   urllib2.urlopen(req)

def retain(url, project, user) :
   values = {"project": project, "user": user, "action": "builds"}
   loginToken = getToken(host, port, user)
   if loginToken is not None :
      values["ltoken"] = loginToken
   data = urllib.urlencode(values)
   req = urllib2.Request(url, data)
   response = urllib2.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, loginToken)


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

retain(url, project, user)

例:ビルドの削除

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

import urllib, urllib2, json, sys, os.path, getpass

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


def deleteBuild(url, user, project, build, action):
    values = {"project": project, "name": build, "user": user, "action": action}
    loginToken = getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.urlopen(req)

host = "localhost"
port = 8080
user = getpass.getuser()
build = "Sample Build"
project = "demosthenes"
build = "demosthenes_3"
action = "delete_build"
url = "http://%s:%d/review/api" % (host, port)
deleteBuild(url, user, project, build, action)
print "Build deleted!"

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

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

import urllib, urllib2, json, sys, os.path, getpass

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

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

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

def from_json(json_object) :
  return View(json_object)

def report(url, project, user, action) :
  values = {"project": project, "user": user, "action": action}
  loginToken = getToken(host, port, user)
  if loginToken is not None :
    values["ltoken"] = loginToken
  data = urllib.urlencode(values)
  req = urllib2.Request(url, data)
  response = urllib2.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)

defects = report(url, project, user, action)
print "Defect types:"
for defect in defects :
  print defect

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

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

import urllib, urllib2, json, sys, os.path, getpass

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

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}
    loginToken = getToken(host, port, user)
    if loginToken is not None :
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    response = urllib2.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)

taxonomies = report(url, project, user, action)
print "Taxonomies:"
for taxonomy in taxonomies :
    print taxonomy

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

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

import urllib, urllib2, json, sys, os.path, getpass

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

def set_defect(url, project, user, action, code, enabled, severity) :
  values = {"project": project, "user": user, "action": action, "code": code, "enabled": enabled, "severity": severity}
  loginToken = getToken(host, port, user)
  if loginToken is not None :
    values["ltoken"] = loginToken
  data = urllib.urlencode(values)
  req = urllib2.Request(url, data)
  response = urllib2.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)

set_defect(url, project, user, action, code, enabled, severity)
print "Defect type %s updated!\nEnabled: %s\nSeverity: %s" % (code, enabled, severity)

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

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

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

import urllib, urllib2, json, sys, os.path, getpass

def getToken(host, port, user) :
    ltoken = os.path.normpath(os.path.expanduser("~/.klocwork/ltoken"))
    ltokenFile = open(ltoken, 'r')
    for r in ltokenFile :
        rd = r.strip().split(';')
        if rd[0] == host and rd[1] == str(port) and rd[2] == user :
            ltokenFile.close()
            return rd[3]
    ltokenFile.close()
 
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 = "project"
url = "http://%s:%d/review/api" % (host, port)
values = {"project": project, "user": user, "action": "metrics"}
 
loginToken = getToken(host, port, user)
if loginToken is not None :
    values["ltoken"] = loginToken
 
values["query"] = "metric:+RNOEXSTAT,+LINESCOMM,+NCNBLOC_FILE,+RMAXLEVEL,+RCYCLOMATIC"
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
try:
    response = urllib2.urlopen(req)
    for record in response :
        print json.loads(record, object_hook=from_json)
except urllib2.HTTPError, error:
    sys.stderr.write('ERROR: %s\n' % str(error))
    sys.stderr.write('%s\n' % error.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 フラグはデータに関連性がある場合にのみ役立ちます。つまり、メトリックの集約が可能であるか、最大値と最小値を決められる場合です。

次の例について

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

import socket, re, platform, os.path

def getToken(host, port, user):
    if host is "localhost":
        host = socket.gethostname()
    userHomePath = os.path.expanduser("~")
    if re.search("Windows", platform.platform()) != None:
        userHomePath = os.environ['UserProfile']
    ltoken = os.path.normpath(os.path.join(userHomePath, ".klocwork", "ltoken"))
    ltokenFile = open(ltoken, 'r')
    for r in ltokenFile:
        rd = r.strip().split(';')
        if rd[0] == socket.getfqdn(host) and rd[1] == str(port) and rd[2] == user:
            ltokenFile.close()
            return rd[3]
    ltokenFile.close()
    return None

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

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

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

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

import urllib, urllib2, json, sys, os.path, getpass, time

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
    loginToken = kwutil.getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.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 urllib2.HTTPError, error:
    sys.stderr.write('ERROR: %s\n' % str(error))
    sys.stderr.write('%s\n' % error.read())

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

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

import urllib, urllib2, json, sys, os.path, getpass, time

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
    loginToken = kwutil.getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken
    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.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 urllib2.HTTPError, error:
    sys.stderr.write('ERROR: %s\n' % str(error))
    sys.stderr.write('%s\n' % error.read())

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

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

import urllib, urllib2, json, time, os.path, getpass, re, platform, sys, socket

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}

    loginToken = kwutil.getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken

    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)

    response = urllib2.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

    loginToken = kwutil.getToken(host, port, user)
    if loginToken is not None:
        values["ltoken"] = loginToken

    data = urllib.urlencode(values)
    req = urllib2.Request(url, data)
    urllib2.urlopen(req)


def wait_for_import(url, user, project):
    isTimeout = 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:
                isTimeout = time.time() > TIME_OUT

            if status.complete or status.failed:
                print status.stage
                incomplete.pop(incomplete.index(status.project))
                break
            elif isTimeout:
                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 urllib2.HTTPError, error:
    sys.stderr.write('ERROR: %s\n' % str(error))
    sys.stderr.write('%s\n' % error.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