Skip to main content

Git スクリプトインターフェースの使用

CODESYS Git Git 用のスクリプトインターフェイスを提供します。このインターフェイスの使用方法の例を以下に示します。また、多くの Git 操作によって生成されるメッセージのテキストベースの出力に関する情報も以下に記載されています

詳細については、以下を参照してください。 スクリプト エンジン API ドキュメント

必要条件

以下の例を実行するには、以下が必要です。

  • CODESYS 3.5.19.30 またはそれ以降

次のコンポーネントも必要です。

  • CODESYS Library Documentation Support (コンパイル済みライブラリを作成するため)

  • CODESYS Git 1.6.0.0 またはそれ以降

  • ローカルの Git インストール

重要

可能な限り SecureString パスワードを使用してください

セキュリティを強化するには、パスワードは.NET SecureString として渡す必要があります。

影響を受ける GIT 操作は以下のとおりです。 clonefetchpullpush

セキュアストリングは、IronPython で次のように作成できます。「パスワード」自体は安全な文字列から取得する必要があり、ここで説明した例のようにスクリプト内のプレーンテキストであってはなりません。内部的には、入力されたパスワードはすべて安全に取り扱われます。 :

        from System.Security import SecureString 

        sec_str_password = SecureString()
        for c in "Passwort":    
            sec_str_password.AppendChar(c)

ご利用時のさらなるセキュリティ対策のため CODESYS Git 以下を参照してください。 CODESYS ギフトのセキュリティ

準備

CODESYS 図書館

だって、ないから CODESYS ライブラリは現在、のソースである Git で管理されています CODESYS ライブラリは必須です。 String Functions.library のライブラリ CODESYS String Libraries 例では製品が使用されています。

リモート Git リポジトリ

この例では、ファイルシステム内のベア Git リポジトリがリモートリポジトリとして使用されます。

準備するには、まず対応するディレクトリを削除してから新しいディレクトリを作成します。

import shutil
import os 

def prepare_empty_dir(empty_dir_path):
    print("Prepare empty directory at", empty_dir_path)
    shutil.rmtree(empty_dir_path, ignore_errors=True)
    if not(os.path.exists(empty_dir_path) and os.path.isdir(empty_dir_path)):
        os.makedirs(empty_dir_path)

その後、空のベア Git リポジトリが作成されます。

import subprocess
def create_bare_git_repository(bare_repository_path):
    print("Create bare git repository at", bare_repository_path)
    create_bare_repository_cmd = 'cmd /c "git -C \"' + bare_repository_path + '\" init --bare"'
    try:
        retcode = subprocess.call(create_bare_repository_cmd, shell=True)
        if retcode < 0:
            raise Exception("Creating bare git repository at " + bare_repository_path + " failed: ", -retcode)
        else:
            print("Creating bare git repository at " + bare_repository_path + " succeeded.")
    except Exception as e:
        print("[ERROR] Creating bare git repository failed: ", e)
        raise

空の Git リポジトリには、以下の内容が格納されています。 CODESYS ライブラリ。

def initialize_bare_git_repository(library_path, local_repository_path, bare_repository_path):
    print("Open library:", library_path)
    project = projects.open(library_path)
     
    print("Initiate local git repository")
    project.git.init(local_repository_path)
    project.git.commit_complete("Create git repo for lib", "user", "mail@mail")
     
    print("Push to remote git repository")
    origin_remote = project.git.remote_add("origin", bare_repository_path)
    project.git.branch_set_upstream_to(origin_remote)
    project.git.push()
    project.git.de_init(cleanUpFileSystem=True)
    project.close()

次のスクリプトは、説明されている機能を実行します。

import os

def main():
    if projects.primary:
        projects.primary.close()

    basepath = "C:\\CODESYS_Projects\\Git_Scripting_Tutorial\\"

    project_basepath = os.path.join(basepath, "projects\\")
    library_file_name = "ExampleLib1.library"
    library_path = os.path.join(project_basepath, library_file_name)

    remote_repo_basepath = os.path.join(basepath, "remotes\\")
    remote_repo_directory_name = "ExampleLib1RemoteRepo"
    remote_repo_path = os.path.join(remote_repo_basepath, remote_repo_directory_name)

    local_repo_basepath = os.path.join(basepath, "repos\\")
    local_repo_directory_name = "ExampleLib1LocalRepo"
    local_repo_path = os.path.join(local_repo_basepath, local_repo_directory_name)

    print("Create and push library to remote git repository")
    
    prepare_empty_dir(remote_repo_path)
    create_bare_git_repository(remote_repo_path)
    initialize_bare_git_repository(library_path, local_repo_path, remote_repo_path)

    print("[Success] All done")


if __name__ == '__main__':
    main()

他の例では、この方法で作成され、コンテンツが提供されているベアの Git リポジトリを使用します。

リモート Git リポジトリのクローン

次の関数が実行されます git clone リモート Git リポジトリ用。

def clone_git_repository(project_basepath, project_file_name, remote_repo_url_or_path, local_repo_path):
    update_flags = VersionUpdateFlags.UpdateAll | VersionUpdateFlags.SilentMode    
    project = git.clone(project_basepath, project_file_name, remote_repo_url_or_path, local_repo_path, update_flags=update_flags)
    project.save()
    return project

新しいブランチの作成とマージ

次の補助関数は、にいくつかの新しいオブジェクトを作成します CODESYS 例としてプロジェクト。

def add_dut(project):
    ST_STRUCT_STR = """\
        a : BOOL;
        b : BIT;
        c : BIT;
    """

    ST_UNION_STR = """\
    TYPE ExampleUnion :
    UNION
        Zahl : INT;
        Prozent : ExampleAlias;
        Bits : ExampleStruct;
    END_UNION
    END_TYPE
    """

   # Create a struct DUT and insert the list of variables just into the right
   # place in line two, row 0 (line numbering starts with line 0)
   example_dut_struct = project.create_dut('ExampleStruct') # DutType.Structure is the default
   example_dut_struct.textual_declaration.insert(2, 0, ST_STRUCT_STR) 

   # Alias types get their "content" via the base type, which will just end up 
   # as one line in the declaration part:    
   # TYPE MyAlias : INT (0..100); END_TYPE 
   example_dut_alias = project.create_dut('ExampleAlias', DutType.Alias, "INT (0..100)") 

   # Instead of injecting the variables into the existing declaration, 
   # one can also just replace the complete declaration part, including the 
   # boilerplate code.
   example_dut_union = project.create_dut('ExampleUnion', DutType.Union)
   example_dut_union.textual_declaration.replace(ST_UNION_STR)

次の補助関数は、のプロジェクト情報内のビルドバージョンをインクリメントします。 CODESYS プロジェクト。

def increment_build_version(project):
    """
    Increment build version in project info.
    """
    info = project.get_project_info()
    old_version = info.version
    info.version = (old_version.Major, old_version.Minor, old_version.Build + 1, 0)
    project.save()

次の関数は、最初に新しいブランチを作成し、このブランチに変更を加え、これらの変更をメインブランチにマージします。

def copy_branch_and_merge(project):
    current_branch = project.git.branch_show_current()
    print("Current branch: ", current_branch.friendly_name)
    project, current_branch = project.git.branch_copy(current_branch, "new_branch", checkout=True)
    print("Current branch: ", current_branch.friendly_name)

    add_dut(project)
    project.git.commit_complete("Added DUT", "user", "mail@mail")

    increment_build_version(project)
    project.git.commit_complete("Incremented build version", "user", "mail@mail")

    project, current_branch = project.git.checkout("master")
    print("Current branch: ", current_branch.friendly_name)
    project, merge_result = project.git.merge("new_branch")
    print("Merged: ", merge_result.ToString())
    project.save()
    return project

次のスクリプトが実行されます。 git clone リモート Git リポジトリの場合、プロジェクトに変更を加え、その変更をリモート Git リポジトリにプッシュします (CopyBranchAndMerge.py)。

def main():
    if projects.primary: 
       projects.primary.close()

    basepath = "C:\\CODESYS_Projects\\Git_Scripting_Tutorial\\"

    project_basepath = os.path.join(basepath, "projects\\")
    library_file_name = "ExampleLib1Cloned.library"

    remote_repo_basepath = os.path.join(basepath, "remotes\\")
    remote_repo_directory_name = "ExampleLib1RemoteRepo"
    remote_repo_path = os.path.join(remote_repo_basepath, remote_repo_directory_name)

    local_repo_basepath = os.path.join(basepath, "repos\\")
    local_repo_directory_name = "ExampleLib1LocalRepo"
    local_repo_path = os.path.join(local_repo_basepath, local_repo_directory_name)

    print("Clone project")
    project = clone_git_repository(project_basepath, library_file_name, remote_repo_path, local_repo_path)
    project = copy_branch_and_merge(project)
    project.git.push()
    project.save()
    project.git.de_init(cleanUpFileSystem=True)
    project.save()
    project.close()
    print("[Success] All done")

if __name__ == '__main__':
    main())

コンパイル済みライブラリの作成

次のスクリプトが実行されます。 git clone の場合 CODESYS リモート Git リポジトリからソースライブラリを作成し、そこからコンパイル済みライブラリを作成する (CreateCompiledLibrary.py)。

import os

class CompileError(Exception):
    pass

def clone_git_repository(project_basepath, project_file_name, remote_repo_url_or_path, local_repo_path):
    update_flags = VersionUpdateFlags.UpdateAll | VersionUpdateFlags.SilentMode
    project = git.clone(project_basepath, project_file_name, remote_repo_url_or_path, local_repo_path, update_flags=update_flags)
    project.save()
    return project

def create_compiled_library(project):
    # requires the CODESYS Library Documentation Support Package!
    project.check_all_pool_objects()
    compile_result_message = system.get_messages(category='{97F48D64-A2A3-4856-B640-75C046E37EA9}')[-1]
    if "0 errors" in compile_result_message:
        project.save_as_compiled_library(destination_name=None)
    else:
        raise CompileError("Compile failed: " + compile_result_message)
    return project

basepath = "D:\\JiraTickets\\GIT-145\\"

project_basepath = os.path.join(basepath, "projects\\")

remote_repo_basepath = os.path.join(basepath, "remotes\\")
remote_repo_directory_name = "StringFunctions.git"
remote_repo_path = os.path.join(remote_repo_basepath, remote_repo_directory_name)

local_repo_basepath = os.path.join(basepath, "repos\\")
local_repo_path = os.path.join(local_repo_basepath, "StringFunctions.git")

print("Clone project")
project = clone_git_repository(project_basepath, "String Functions Cloned.library", remote_repo_path, local_repo_path)
project = create_compiled_library(project)
project.git.de_init(cleanUpFileSystem=True)
project.close()

print("[Success] All done")

リモート Git リポジトリからライブラリをインストールする

次のスクリプトが実行されます。 git clone の場合 CODESYS リモート Git リポジトリのソースライブラリで、このライブラリを現在のリポジトリにインストールします CODESYS インスタンス (InstallLibrary.py)。

import os

def clone_git_repository(project_directory_path, project_file_name, remote_repo_url_or_path, local_repo_path):
    update_flags = VersionUpdateFlags.UpdateAll | VersionUpdateFlags.SilentMode
    project = git.clone(project_directory_path, project_file_name, remote_repo_url_or_path, local_repo_path, update_flags=update_flags)
    project.save()
    return project

def install_library(project):
    library_repo = librarymanager.repositories[0]
    librarymanager.install_library(project.path, library_repo, True)

def main():
    if projects.primary:
        projects.primary.close()

     basepath = "C:\\CODESYS_Projects\\Git_Scripting_Tutorial\\"

    project_basepath = os.path.join(basepath, "projects\\")
    library_file_name = "ExampleLib1Cloned2.library"

    remote_repo_basepath = os.path.join(basepath, "remotes\\")
    remote_repo_directory_name = "ExampleLib1RemoteRepo"
    remote_repo_path = os.path.join(remote_repo_basepath, remote_repo_directory_name)

    local_repo_basepath = os.path.join(basepath, "repos\\")
    local_repo_directory_name = "ExampleLib1LocalRepo"
    local_repo_path = os.path.join(local_repo_basepath, local_repo_directory_name)

    print("Clone project")
    project = clone_git_repository(project_basepath, library_file_name, remote_repo_path, local_repo_path)

    print("Install library")
    install_library(project)
    project.git.de_init(cleanUpFileSystem=True)
    project.close()

    print("[Success] All done")

if __name__ == '__main__':
    main()

Git 操作のメッセージ出力

使用する場合 CODESYS Gitほとんどのコマンドはテキストベースの出力を提供します。実行時 CODESYS コマンドラインでは、以下を実行すると自動的に出力されます。 CODESYS Git スクリプトドライバ経由のコマンド。使用時 CODESYS GitCODESYS Development System、出力はメッセージウィンドウにも表示されます。

Structure of the messages: Git:<severity>: [<time>] <text>

In the user interface of CODESYS Git, the output is reduced to: [<time>] <text>

  • severity: メッセージカテゴリ。カテゴリは情報提供のみを目的とするものから重大なエラーまで多岐にわたります

  • time: メッセージの正確な時刻。フォーマット: HH:MM:SS

  • text: メッセージの内容。標準の Git コマンドの場合、内容はスクリプトドライバの呼び出しと同じ結果をもたらすコマンドラインコマンドに対応しています。 CODESYS Git 標準の Git コマンドに対応しないコマンド (例: リポジトリからプロジェクトを復元) に、実行されたアクションを説明するメッセージテキストが表示されます。

Commands with multiple messages:

一部のコマンド (たとえば、 git log)、出力は複数のメッセージに分割されます。 git log、表示された各コミットは個別のメッセージに表示されます。この場合は、これらのメッセージが「」の一部であることを明確にしておきます。 git log command を指定すると、メッセージ内の元のコマンドが参照されます。