ソースコード構造解析ツール『Understand』は、大規模で複雑なプログラムを素早く解析するための多彩な機能を搭載しています。 アーキテクチャから個々のクラスや関数まで、あらゆるレベルでソースコードを解析し、プログラムの制御フローや構造、クラス継承、関数や変数の関係など、さまざまな角度から見える化します。

車載ソリューションの記事紹介

テクマトリックスでは車載ソフトウェア開発向けのソリューションを提案しています。
ツールチェーンとしてUnderstandが含まれていますので、ご関心のある方は「こちらの記事」をご覧ください。

2020/11/02

UnderstandをSVN連携して、2つのリビジョンを比較する

以前、「UnderstandをGit連携して、2つのリビジョンを比較する」において、 
UnderstandをGit連携することで2つのリビジョンを簡単にプロジェクト比較する機能の設定方法をご紹介しました。
これに対して多くのお客様から、「SVNでも連携できると嬉しい」という声をいただきました。

今回は、Understandのユーザーツール機能を使用して、SVNリポジトリの2つのリビジョンを指定することで、各リビジョンを自動的に解析し、比較する方法をご案内します。
本手順によりSVNでも任意のリビジョンを2つ指定いただくだけで、簡単にリビジョン間の解析差分を確認いただくことが可能となります。

これにより、例えばSVNでも以下のようなユースケースでご利用いただくことが考えられます。

ユースケース

  • 開発者のユースケース
    developブランチの同一ブランチ内の前回のリビジョンと今回のリビジョンを、開発者自身がCompareグラフやソースコード差分機能を通して差分を確認する。また、比較結果となる画像をpngファイルで出力し、変更設計書などのドキュメントに張り付けてSVNでコードと一緒に管理する。

  • レビュアーのユースケース
    メインブランチにコミットする直前のリビジョンと開発スタート時のリビジョンを比較して、差分をチェックする。テスト計画レビューなどでUnderstandで確認したコードベースの差分と、テスト項目の比較をする。
今回は分析するサンプルコードとして、
「C/C++のオープンソースプロジェクト︓tortoisesvn」のリポジトリを使⽤することにします。



目次

  • 前提条件
  • 事前準備
    • 準備1:SVNリポジトリ
    • 準備2:batファイルの配置
    • 準備3:ユーザーツールの設定
  • 実施手順:リビジョン番号を2つ指定し、リビジョンの比較を行う。
  • 結果の確認

前提条件

  1. 動作確認済環境

    • Windows 10 64bit
    • Understand 5.1 (Build 1022)
    • 有効なUnderstandライセンス(APIライセンスは不要)
    • SVN コマンドラインツールインストール済
      (例)以下のPath設定は[https://www.visualsvn.com/downloads/]から、[Apache Subversion command line tools]をDownloadし、[C:\tools]ディレクトリにインストールした場合の例
    • 環境変数[Path]に以下が追加済
      (SVNクライアント及びUnderstandのインストール先に合わせて変えてください。)
        • C:\Program Files\SciTools\bin\pc-win64
        • C:\tools\Apache-Subversion-1.11.1\bin
  2. 解析対象

    • 言語:C/C++(Fuzzy)
    • 解析コード:tortoisesvn(オープンソース)
    • リポジトリパス:
      https://svn.code.sf.net/p/tortoisesvn/code/trunk/src/Utils
      ※サンプルでは気軽にお試しいただけるようコード量調整のため、Utilsモジュールのみを指定しております。

    事前準備

    1. SVNリポジトリ

      1. 今回のサンプルではオープンソースのSVNリポジトリを使用します。
        このため、ご試用いただく上でお客様側でSVNリポジトリを準備いただく必要はありません。お客様側にて準備されたSVNリポジトリに接続される場合には後述の実施手順3で入力するパラメータを環境に合わせて変更してください。

    2. batファイルの配置
      1. ワークスペースを作成します。
        Compareディレクトリを作成し、Compareディレクトリ直下にSVNworkディレクトリを作成します。
        ○パスの例
        • C:\work\Compare
        • C:\work\Compare\SVNwork
      2. 本ブログ最後尾に記載の各batファイルをCompareディレクトリ直下に配置します。
        ○batファイルの配置パスの例
        • C:\work\Compare\CompareSVNrev.bat
        ○配置するbatファイル
        • CompareSVNrev.bat

        なお、batファイル内でUnderstandプロジェクトの解析を行う際に言語の指定を行っております。今回はC/C++言語のFuzzyモードでの解析となります。

    3. ユーザーツールの設定
      1. 本ブログ最後尾に記載の scitools.iniを一時ファイルとして任意のディレクトリに保存します。
      2. UnderstandのGUIを起動し、[メニューバー]-[ツール]-[オプション]-[ユーザーツール]を選択します。
      3. ユーザーツール
      4. [ユーザーツール]の[インポート]ボタンを押し、保存したiniファイルを指定します。
      5. [ユーザーツールのインポート]画面において、[すべて]ボタンを押し、すべてのチェックボックスが選択された状態にして[インポート]ボタンを押します。
        ユーザーツールのインポート

      6. ユーザーツール内で、以下計3箇所を修正します。
        • [svn\undCompare]の設定
          svn\undCompareの設定

          • [コマンド(C)]:[batファイルの配置]項で配置した[CompareSVNrev.bat]ファイルのパスを指定します。
          • [パラメーター(P)]
            PathKindの選択肢はご使用される際に"URL"または"DirectoryPath"のいずれかを毎回選択いただく必要があります。
            いずれかを優先的に使用されたい場合には、不要な選択肢を削除いただくか、選択肢の順番を入れ替えていただき普段使用される選択肢を先頭にしてください。
            repoPathは初期値では"defaultValue"の文字列が入力されています。
            後述の実施手順3の中で実行毎に指定頂くことが可能ですが、
            デフォルト値を設定されたい場合には、以下の例のような文字列に変更いただくことができます。
            (例)C:\work\CI\SvnRepository\repo
            (例)https://svn.code.sf.net/p/tortoisesvn/code/trunk/src/Utils
          • [初期ディレクトリ]:Compareディレクトリ直下の[SVNwork]ディレクトリを指定します。
            初期ディレクトリパス
            (例)C:\work\Compare\SVNwork
      7.  [OK]ボタンを押します。これでユーザーツールの設定は完了です。
        ※Understand設定ファイル(C:\Users\(ユーザー名)\AppData\Roaming\SciTools\Understand.ini)を削除されますと、本ユーザーツールの設定は削除されます。
        予め[ユーザーツールのエクスポート]より設定内容をバックアップしておくことをお勧めいたします。

    実施手順

    1. Understand(GUI)を起動した状態にします。
      ※後にオープンエラーが発生することを防ぐため、プロジェクトは開かないでください。
      ユーザーツールから[svn]-[undCompare]を選択

    2. メニューバーから[ツール]-[ユーザーツール]-[svn]-[undCompare]を押します。

      svn\undCompareのダイアログの入力例(URL指定)

      (参考)svn\undCompareのダイアログの入力例(DirectoryPath指定)


    3. 表示されたダイアログにおいて各値を指定し、OKボタンを押します。
      • PathKind:"URL"を選択(お客様環境に接続する場合は環境に合わせて指定)
      • repoPath:https://svn.code.sf.net/p/tortoisesvn/code/trunk/src/Utils
        (リポジトリパスを指定してください:[実施手順5(補足)]を参照)
      • rev_A:比較元(通常は新ver)
      • rev_B:比較先(通常は旧ver)
        [サンプルプロジェクトお試し用リビジョン番号]
        新Rev:24147
        旧Rev:23880

    4. 以下のような実行ログが出力され、新しいUnderstandの画面が立ち上がり、その画面でA.udbが自動的に開けば成功です。
      実行ログ
    5. (実施手順3の補足)パラメーターとbatファイル内で実行されるsvnコマンドの関係
      指定したパラメーターと実行されるsvnコマンドの関係を説明します。
      batファイル内のsvnコマンド自体はお客様側で変更いただく必要はありませんが、batファイル内容を把握、もしくはカスタマイズされる場合の参考情報として記載いたします。
        • リポジトリパスがURLの場合
          PathKindは"URL"を指定
          repoPathは該当のリポジトリURLを指定
          revA, revBは指定のリビジョンを指定
          (例)PathKindを"URL"、repoPathを
          https://svn.code.sf.net/p/tortoisesvn/code/trunk/src/Utils
          、リビジョンを23880と指定した場合、以下が実行されます。
          svn co -r 23880 https://svn.code.sf.net/p/tortoisesvn/code/trunk/src/Utils

          ※batファイル側ではプロトコルへの制限はかけておりませんので、
          svn/http/httpsなどsvnコマンドで対応しているプロトコルが使用可能です。(リポジトリ側では制限がある場合がございます。)
          ※下記に示すように利便性を考え、fileプロトコルの場合のみ、ディレクトリパス指定で利用できるように、batファイル側で調整しております。
        • リポジトリパスがディレクトリパスの場合
          SVNのリポジトリ情報が含まれているrepoディレクトリをご指定ください。
          PathKindは"DirectoryPath"を指定
          repoPathは該当リポジトリのrepoディレクトリのパスを指定
          revA, revBは指定のリビジョンを指定
          (例)PathKindを"DirectoryPath"、repoPathを
          C:\work\CI\SvnRepository\repo
          、リビジョンを9と指定した場合、
          以下が実行されます。
          svn co -r 9 file:///C:/work/CI/SvnRepository/repo

    結果の確認

    以降は「UnderstandをGit連携して、2つのリビジョンを比較する」の記事と同様になります。
    今回のサンプルでは、例えば以下のように機能をお試しください。
    • [エンティティフィルター]→[BaseWindow.cpp]を右クリックし、
      ButterflyCompareグラフを確認します。

      [BaseWindow.cpp]のButterfly Compareグラフ

    • [ツール]→[比較]→[ファイル/フォルダの比較]から表示されるダイアログにおいて、
      AディレクトリとBディレクトリを比較し、[MiscUI\BaseWindows.cpp]を選択の上、ファイル内の差分を表示します。

      [ファイル/フォルダの比較]のダイアログ

      [ファイル/フォルダの比較]機能によるファイル内差分の表示

    • [レポート]→[プロジェクトインタラクティブレポート]→[Changed Entities]より表示されたダイアログで、全てデフォルト値でOKボタンを押すと表示されるIReportからメトリクス差分を確認します。

      [Changed Entities]のダイアログ
      ChangedEntitiesのレポート
      (Entityのリンクよりコードへジャンプ可能)



    ぜひお試しください。


    各設定ファイルの例

    [CompareSVNRev.batファイルの中身]
    @echo off
    setlocal enabledelayedexpansion
    rd /s /q ..\A
    rd /s /q ..\B
    del *.udb
    if ""%2""=="""" goto END
    if ""%3""=="""" goto END
    if ""%4""=="""" goto END
    set repoPath=
    if ""%1""==""URL"" ( 
      set repoPath=%2
      echo !repoPath!
    ) else if ""%1""==""DirectoryPath"" (
      if exist %2 (
        echo "Directory Path Exist"
      ) else (
        echo "Directory Path Not Exist"
        goto END
      )
      set repoPath="file:///%2"
      echo !repoPath!
    ) else (
      echo "Input Error"
    )
    mkdir B
    cd B
    und create -db B.udb -languages c++
    svn co -r %4 !repoPath!
    und add . B.udb
    und settings -AddMode Relative B.udb
    und analyze -all -db B.udb
    cd ../
    xcopy .\* ..\ /E
    move .\*.udb ..\B\
    rd /s /q B
    mkdir A
    cd A
    und create -db A.udb -languages c++
    svn co -r %3 !repoPath!
    und add . A.udb
    und settings -AddMode Relative A.udb
    und analyze -all -db A.udb
    und settings -ComparisonProjectPath ..\B\B.udb -db A.udb
    cd ../
    xcopy .\* ..\ /E
    move .\*.udb ..\A\
    rd /s /q A
    understand ..\A\A.udb
    goto END
    :END
    echo Finish

    [scitools.iniファイルの中⾝](コピーされる際は行の折り返し箇所に改⾏が⼊らないようご注意ください)
    [commandcapture]
    usertools\storedtools\svn%5CundCompare\command=C:\\work\\Compare\\CompareSVNrev.bat
    usertools\storedtools\svn%5CundCompare\parameters="$PromptForSelect \"PathKind=DirectoryPath;URL\" $PromptForText  \"repoPath=defaultValue\" $PromptForText  rev_A(usually_new) $PromptForText rev_B(usually_old)"
    usertools\storedtools\svn%5CundCompare\iconfile=
    usertools\storedtools\svn%5CundCompare\commanddir=C:\\work\\Compare\\SVNwork
    usertools\storedtools\svn%5CundCompare\input=0
    usertools\storedtools\svn%5CundCompare\output=1
    usertools\storedtools\svn%5CundCompare\uperlscript=false
    usertools\storedtools\svn%5CundCompare\addpopup=true
    usertools\storedtools\svn%5CundCompare\addmenu=true
    usertools\storedtools\svn%5CundCompare\addtoolbar=true
    usertools\storedtools\svn%5CundCompare\runsave=false
    usertools\storedtools\svn%5CundCompare\runparsechanged=false
    usertools\storedtools\svn%5CundCompare\runparseall=false
    usertools\storedtools\svn%5CundCompare\runrescan=false
    usertools\storedtools\svn%5CundCompare\runBefore=false
    usertools\storedtools\svn%5CundCompare\runafter=false
    usertools\storedtools\names=svn\\undCompare