Utilisation de l'interface de script Git
CODESYS Git fournit une interface de script pour Git. Des exemples d'utilisation de l'interface sont présentés ci-dessous. Vous trouverez également ci-dessous des informations sur la sortie textuelle des messages générés par de nombreuses opérations Git
Pour plus d'informations, voir : Documentation de l'API du moteur de script
Exigences
Pour exécuter les exemples ci-dessous, les éléments suivants sont requis :
CODESYS 3.5.19.30 ou supérieur
Les composants suivants sont également requis :
CODESYS Library Documentation Support (pour créer la bibliothèque compilée)
CODESYS Git 1.6.0.0 ou version ultérieure
Une installation Git locale
Important
Utilisez des mots de passe SecureString dans la mesure du possible
Pour une sécurité accrue, les mots de passe doivent être transmis sous forme de .NET SecureString.
Les opérations GIT concernées sont les suivantes : clone
, fetch
, pull
, push
SecureStrings peut être créé dans IronPython comme suit. Le « mot de passe » lui-même doit provenir d'une chaîne sécurisée et non, comme ici à des fins de démonstration, être en texte brut dans le script. En interne, chaque mot de passe fourni est géré de manière sécurisée
from System.Security import SecureString sec_str_password = SecureString() for c in "Passwort": sec_str_password.AppendChar(c)
Pour des mesures de sécurité supplémentaires lors de l'utilisation CODESYS Git voir : Sécurité pour CODESYS Git
Préparation
CODESYS bibliothèque
Parce que non CODESYS les bibliothèques sont actuellement gérées dans Git, les sources d'un CODESYS une bibliothèque est requise. String Functions.library
bibliothèque de CODESYS String Libraries le produit est utilisé dans les exemples.
Dépôt Git distant
Pour cet exemple, un référentiel Git nu dans le système de fichiers est utilisé comme référentiel distant.
Pour vous préparer, supprimez d’abord le répertoire correspondant puis créez-en un nouveau.
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)
Un dépôt Git vide est ensuite créé.
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
Le dépôt Git vide est rempli avec le contenu du CODESYS bibliothèque.
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()
Le script suivant exécute les fonctions décrites.
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()
Le référentiel Git nu ainsi créé et fourni avec son contenu est utilisé pour les autres exemples.
Clonage d'un dépôt Git distant
La fonction suivante exécute git clone
pour un dépôt Git distant.
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
Créer et fusionner une nouvelle branche
La fonction auxiliaire suivante crée de nouveaux objets dans un CODESYS projet à titre d'exemple.
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 fonction auxiliaire suivante incrémente la version de build dans les informations de projet d'un CODESYS projet.
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 fonction suivante crée d'abord une nouvelle branche et apporte des modifications à cette branche, puis fusionne ces modifications dans la branche 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
Le script suivant s'exécute git clone
pour un dépôt Git distant, apporte des modifications au projet, puis transmet les modifications au référentiel Git distant (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())
Création d'une bibliothèque compilée
Le script suivant s'exécute git clone
pour un CODESYS bibliothèque source à partir d'un référentiel Git distant, puis crée une bibliothèque compilée à partir de celui-ci (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")
Installer une bibliothèque à partir d'un référentiel Git distant
Le script suivant s'exécute git clone
pour un CODESYS bibliothèque source à partir d'un référentiel Git distant et installe cette bibliothèque dans le CODESYS exemple (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()
Sortie de message pour les opérations Git
Lors de l'utilisation CODESYS Git, la plupart des commandes fournissent une sortie basée sur du texte. Lors de la course CODESYS dans la ligne de commande, cette sortie est automatiquement générée lors de l'exécution de CODESYS Git commandes via le pilote de script. Lors de l'utilisation CODESYS Git dans CODESYS Development System, les résultats apparaissent également dans la fenêtre de message.
Structure of the messages: Git:<severity>: [<time>] <text>
In the user interface of CODESYS Git, the output is reduced to: [<time>] <text>
severity
: catégorie de message. Les catégories vont de l'erreur purement informative à l'erreur critiquetime
: Heure exacte du message. Format :HH:MM:SS
text
: Contenu du message. Pour les commandes Git standard, le contenu correspond à la commande de ligne de commande qui fournirait le même résultat que l'appel du pilote de script effectué. CODESYS Git commandes qui ne correspondent pas à une commande Git standard (par exemple, Restaurer le projet à partir du référentiel), le texte du message explique l'action effectuée.
Commands with multiple messages:
Pour certaines commandes (par exemple, git log
), la sortie est divisée en plusieurs messages. Dans le cas de git log
, chaque validation affichée est affichée dans un message distinct. Dans ce cas, afin de préciser que ces messages font partie du git log
commande, une référence est faite à la commande d'origine dans les messages.