Usare l'interfaccia di scripting Git
CODESYS Git fornisce un'interfaccia di scripting per Git. Di seguito sono riportati alcuni esempi di come utilizzare l'interfaccia. Di seguito troverai anche informazioni sull'output testuale dei messaggi generati da molte operazioni Git
Per ulteriori informazioni, vedere: Documentazione dell'API del motore di script
Requisiti
Per eseguire gli esempi seguenti, è necessario quanto segue:
CODESYS 3.5.19.30 o versioni successive
Sono inoltre necessari i seguenti componenti:
CODESYS Library Documentation Support (per creare la libreria compilata)
CODESYS Git 1.6.0.0 o versioni successive
Un'installazione Git locale
Importante
Usa le password SecureString quando possibile
Per una maggiore sicurezza, le password devono essere passate come .NET SecureString.
Le operazioni GIT interessate sono: clone
, fetch
, pull
, push
SecureStrings possono essere create in IronPython come segue. La «password» stessa deve provenire da una stringa sicura e non, come qui a scopo dimostrativo, essere in testo semplice nello script. Internamente, ogni password fornita viene gestita in modo sicuro
from System.Security import SecureString sec_str_password = SecureString() for c in "Passwort": sec_str_password.AppendChar(c)
Per ulteriori misure di sicurezza durante l'utilizzo CODESYS Git vedi: Sicurezza per CODESYS Git
Preparazione
CODESYS biblioteca
Perché no CODESYS le librerie sono attualmente gestite in Git, i sorgenti di a CODESYS le librerie sono obbligatorie. String Functions.library
libreria da CODESYS String Libraries il prodotto viene utilizzato negli esempi.
Repository Git remoto
Per questo esempio, un repository Git nudo nel file system viene utilizzato come repository remoto.
Per prepararti, elimina prima la cartella corrispondente e poi creane una nuova.
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)
Viene quindi creato un repository Git vuoto.
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
Il repository Git vuoto e nudo è riempito con il contenuto di CODESYS libreria.
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()
Lo script seguente esegue le funzioni descritte.
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()
Il semplice repository Git creato in questo modo e dotato di contenuti viene utilizzato per gli altri esempi.
Clonazione di un repository Git remoto
La seguente funzione viene eseguita git clone
per un repository Git remoto.
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
Creazione e fusione di una nuova filiale
La seguente funzione ausiliaria crea alcuni nuovi oggetti in un CODESYS progetto come esempio.
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)
La seguente funzione ausiliaria incrementa la versione di build nelle informazioni di progetto di un CODESYS progetto.
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()
La seguente funzione crea prima un nuovo ramo e apporta modifiche a questo ramo, quindi unisce nuovamente queste modifiche nel ramo principale.
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
Il seguente script viene eseguito git clone
per un repository Git remoto, apporta modifiche al progetto e quindi invia le modifiche al repository Git remoto (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())
Creazione di una libreria compilata
Il seguente script viene eseguito git clone
per un CODESYS libreria sorgente da un repository Git remoto e quindi crea una libreria compilata da esso (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")
Installazione di una libreria da un repository Git remoto
Il seguente script viene eseguito git clone
per un CODESYS libreria sorgente da un repository Git remoto e installa questa libreria nella versione corrente CODESYS istanza (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()
Output di messaggi per operazioni Git
Quando si utilizza CODESYS Git, la maggior parte dei comandi fornisce un output basato su testo. Durante l'esecuzione CODESYS nella riga di comando, viene emesso automaticamente durante l'esecuzione di CODESYS Git comandi tramite il driver di script. Quando si utilizza CODESYS Git nel CODESYS Development System, le uscite vengono visualizzate anche nella finestra dei messaggi.
Structure of the messages: Git:<severity>: [<time>] <text>
In the user interface of CODESYS Git, the output is reduced to: [<time>] <text>
severity
: categoria di messaggi. Le categorie vanno da quelle puramente informative a quelle relative agli errori criticitime
: ora esatta del messaggio. Formato:HH:MM:SS
text
: Contenuto del messaggio. Per i comandi Git standard, il contenuto corrisponde al comando della riga di comando che fornirebbe lo stesso risultato della chiamata effettuata al driver di script. CODESYS Git comandi che non corrispondono a un comando Git standard (ad esempio, Recupera il progetto dal repository), il testo del messaggio spiega l'azione eseguita.
Commands with multiple messages:
Per alcuni comandi (ad esempio, git log
), l'output è suddiviso in più messaggi. Nel caso di git log
, ogni commit visualizzato viene mostrato in un messaggio separato. In questo caso, per chiarire che questi messaggi fanno parte del git log
comando, viene fatto riferimento al comando originale nei messaggi.