2013-05-24 12 views
6

Unser Team verwendet Enterprise Architect version 10 und SVN für das Repository. Da die Dateigröße EAP ziemlich groß ist (z. B. 80 MB), exportieren wir jedes Paket in separate XMI und speichern es in SVN. Die Datei EAP selbst ist nach einem Meilenstein festgeschrieben. Das Problem ist, die Datei EAP mit der Arbeit von Kollegen während der Entwicklung zu synchronisieren, müssen wir viele XMI (z. B. insgesamt 500 Dateien) importieren.Effiziente Möglichkeit zum Batch-Import von XMI in Enterprise Architect

Ich weiß, dass, sobald die EAP Datei aktualisiert wird, können wir Package Control -> Get All Latest. Daher tritt dieses Problem nur während der parallelen Entwicklung auf.

Wir haben Tastatur shorcuts verwendet, um den Import wie folgt zu tun:

  1. Ctrl + Alt + I (Import-Paket von XMI Datei)
  2. den Dateinamen auswählen
  3. importieren
  4. Alt + I (Import)
  5. Geben Sie (Yes)
  6. Wiederholen Sie Schritt Nummer 2 bis 4, bis Modul

Aber noch fertig, Hunderte von Datei ineffizient ist zu importieren.

Ich habe überprüft, dass das Control Package Batch-Import/Export hat. Der Stapelimport/-export funktioniert, wenn ich die XMI Filename explizit hartcodierte, aber die Optionen sind nicht verfügbar, wenn Versionskontrolle verwendet wird (Optionen für Stapelimport/-export sind grau dargestellt).

Gibt es bessere Möglichkeiten, EAP und XMI Dateien zu synchronisieren?

Antwort

4

Es gibt eine scripting Schnittstelle in EA. Möglicherweise können Sie den Import damit automatisieren. Ich habe es nicht benutzt, aber es ist wahrscheinlich ziemlich gut.

Ich bin mir nicht sicher, ob ich Ihre Arbeitsumgebung vollständig verstehe, aber ich habe einige allgemeine Punkte, die von Interesse sein könnten. Es könnte sein, dass, wenn Sie EA auf eine andere Weise verwenden (besonders mein erster Punkt unten), die Notwendigkeit des Batch-Imports weggehen könnte.

Multiworker

Erstens können mehrere Personen gleichzeitig auf der gleichen EAP-Datei arbeiten. Die EAP-Datei ist nichts anderes als eine Access-Datenbankdatei, und EA verwendet Sperren, um mehrere Personen zu stoppen, die dasselbe Paket zur gleichen Zeit bearbeiten. Aber Sie können bequem mehrere Personen haben, die gleichzeitig verschiedene Pakete in einer EAP-Datei bearbeiten. Die EAP-Datei irgendwo auf eine Dateifreigabe zu stellen, ist eine gute Möglichkeit, dies zu tun.

Inbuilt Revision Control

Zweitens kann EA interagieren direkt mit SVN (und anderen Versionskontrollsystemen). Siehe this.Kurz gesagt, Sie können Ihre EAP-Datei so einrichten, dass einzelne Pakete (und alles darunter) SVN-gesteuert werden. Sie können dann ein einzelnes Paket auschecken, es bearbeiten und es wieder einchecken. Oder Sie können sogar den gesamten Zweig unterhalb eines Pakets auschecken (einschließlich Unterpaketen, die selbst SVN-kontrolliert sind).

Unter der Haube importiert und exportiert EA XMI-Dateien und prüft sie in und aus SVN, während die EAP-Datei immer die Hauptversion ist. Genau wie das, was Sie von Hand machen, aber automatisiert. Es macht Sinn, da Sie alle die einzige EAP-Datei verwenden können. Sie müssen ein wenig vorsichtig zurückrollen - Links, die von Objekten in älteren Versionen eines Pakets stammen, verweisen möglicherweise auf Objekte, die nicht mehr existieren (Sie können sich jedoch die Fehler im Importprotokoll ansehen, um festzustellen, ob dies der Fall ist). Es braucht ein bisschen gewöhnungsbedürftig, aber es funktioniert ziemlich gut.

Es gibt auch die integrierte Paket-Baselining-Funktionalität - das könnte sowieso alles sein, was Sie brauchen, und funktioniert ganz gut, besonders wenn Sie alle die gleiche EAP-Datei verwenden.

Bigger Database Engine

Drittens müssen Sie nicht überhaupt eine EAP-Datei haben. Die Datenbank des Modells kann sich in jedem geeigneten Datenbanksystem (MySQL, SQL Server, Oracle, usw.) befinden. Das gibt Ihnen alle möglichen Optionen für die Skalierung, wie es verwendet wird, wie es über ein WAN/Internet, etc.

Kurz gesagt, Sparx waren ziemlich vernünftig darüber, wie EA in einer Multi-Worker-Umgebung verwendet werden kann, und es lohnt sich, das auszubeuten.

+0

Ok Lassen Sie mich das Scripting und die eingebaute Revisionskontrolle überprüfen. – David

+0

Die eingebaute Revisionskontrolle ist ähnlich wie das, was wir gerade gemacht haben. Es gibt kein Problem, das Paket an SVN einzuchecken und den XMI-Export zu erhalten. Das Problem liegt beim ersten Import von XMI, da jedes Teammitglied seine eigene EAP-Datei verwendet. Für das Scripting habe ich nur einige Beispiele und Erklärungen gesehen :( – David

+0

Ist die EAP-Datei jedes Teammitglieds nominell identisch? Wenn ja, könntest du einfach dasjenige auswählen, das komplett auf dem neuesten Stand ist (oder ein solches erstellen), es auf eine Dateifreigabe kleben, und dann kann jeder seine eigenen aufgeben und anfangen, diese zu verwenden. Sie können dann diese einzelne EAP-Datei einrichten, um sich in SVN zu integrieren. Sie werden Kontinuität in Ihrem Überarbeitungsverlauf verlieren. Kurz gesagt, ich schlage eine einmalige Anstrengung vor, um eine zu bekommen einzelne EAP-Datei und verwenden Sie ab sofort die eingebaute automatische SVN-Integration von EA – bazza

1

Ich habe den EA-Skript mit JScript für die Automatisierung erstellt

Hier das Skript wird den Export zu tun:

!INC Local Scripts.EAConstants-JScript 

/* 
* Script Name : Export List of SVN Packages 
* Author  : SDK 
* Purpose  : Export a package and all of its subpackages information related to version 
*    controlled. The exported file then can be used to automatically import 
*    the XMIs 
* Date  : 30 July 2013 
* HOW TO USE : 1. Select the package that you would like to export in the Project Browser 
*    2. Change the output filepath in this script if necessary. 
*     By default it is "D:\\EAOutput.txt" 
*    3. Send the output file to your colleague who wanted to import the XMIs 
*/ 

var f; 

function main() 
{ 
    // UPDATE THE FOLLOWING OUTPUT FILE PATH IF NECESSARY 
    var filename = "D:\\EAOutput.txt"; 

    var ForReading = 1, ForWriting = 2, ForAppending = 8; 

    Repository.EnsureOutputVisible("Script"); 
    Repository.ClearOutput("Script"); 
    Session.Output("Start generating output...please wait..."); 

    var treeSelectedType = Repository.GetTreeSelectedItemType(); 

    switch (treeSelectedType) 
    { 
     case otPackage: 
     { 
      var fso = new ActiveXObject("Scripting.FileSystemObject"); 
      f = fso.OpenTextFile(filename, ForWriting, true); 

      var selectedObject as EA.Package; 
      selectedObject = Repository.GetContextObject(); 
      reportPackage(selectedObject); 
      loopChildPackages(selectedObject); 

      f.Close(); 
      Session.Output("Done! Check your output at " + filename); 
      break; 
     } 
     default: 
     { 
      Session.Prompt("This script does not support items of this type.", promptOK); 
     } 
    } 
} 

function loopChildPackages(thePackage) 
{ 
    for (var j = 0 ; j < thePackage.Packages.Count; j++) 
    { 
     var child as EA.Package; 
     child = thePackage.Packages.GetAt(j); 
     reportPackage(child); 
     loopChildPackages(child); 
    } 
} 

function getParentPath(childPackage) 
{ 
    if (childPackage.ParentID != 0) 
    { 
     var parentPackage as EA.Package; 
     parentPackage = Repository.GetPackageByID(childPackage.ParentID); 
     return getParentPath(parentPackage) + "/" + parentPackage.Name; 
    } 
    return ""; 
} 

function reportPackage(thePackage) 
{ 
    f.WriteLine("GUID=" + thePackage.PackageGUID + ";" 
        + "NAME=" + thePackage.Name + ";" 
        + "VCCFG=" + getVCCFG(thePackage) + ";" 
        + "XML=" + thePackage.XMLPath + ";" 
        + "PARENT=" + getParentPath(thePackage).substring(1) + ";" 
    ); 
} 

function getVCCFG(thePackage) 
{ 
    if (thePackage.IsVersionControlled) 
    { 
     var array = new Array(); 
     array = (thePackage.Flags).split(";"); 

     for (var z = 0 ; z < array.length; z++) 
     { 
      var pos = array[z].indexOf('='); 

      if (pos > 0) 
      { 
       var key = array[z].substring(0, pos); 
       var value = array[z].substring(pos + 1); 

       if (key=="VCCFG") 
       { 
        return (value); 
       } 
      } 
     } 
    } 
    return ""; 
} 

main(); 

und das Skript den Import zu tun:

!INC Local Scripts.EAConstants-JScript 

/* 
* Script Name : Import List Of SVN Packages 
* Author  : SDK 
* Purpose  : Imports a package with all of its sub packages generated from 
*    "Export List Of SVN Packages" script 
* Date  : 01 Aug 2013 
* HOW TO USE : 1. Get the output file generated by "Export List Of SVN Packages" script 
*     from your colleague 
*    2. Get the XMIs in the SVN local copy 
*    3. Change the path to the output file in this script if necessary (var filename). 
*     By default it is "D:\\EAOutput.txt" 
*    4. Change the path to local SVN 
*    5. Run the script 
*/ 

var f; 
var svnPath; 

function main() 
{ 
    // CHANGE THE FOLLOWING TWO LINES ACCORDING TO YOUR INPUT AND LOCAL SVN COPY 
    var filename = "D:\\EAOutput.txt"; 
    svnPath = "D:\\svn.xxx.com\\yyy\\docs\\design\\"; 

    var ForReading = 1, ForWriting = 2, ForAppending = 8; 

    Repository.EnsureOutputVisible("Script"); 
    Repository.ClearOutput("Script"); 
    Session.Output("[INFO] Start importing packages from " + filename + ". Please wait..."); 

    var fso = new ActiveXObject("Scripting.FileSystemObject"); 
    f = fso.OpenTextFile(filename, ForReading); 

    // Read from the file and display the results. 
    while (!f.AtEndOfStream) 
    { 
     var r = f.ReadLine(); 
     parseLine(r); 
     Session.Output("--------------------------------------------------------------------------------"); 
    } 

    f.Close(); 
    Session.Output("[INFO] Finished"); 
} 

function parseLine(line) 
{ 
    Session.Output("[INFO] Parsing " + line); 

    var array = new Array(); 
    array = (line).split(";"); 

    var guid; 
    var name; 
    var isVersionControlled; 
    var xmlPath; 
    var parentPath; 

    isVersionControlled = false; 
    xmlPath = ""; 

    for (var z = 0 ; z < array.length; z++) 
    { 
     var pos = array[z].indexOf('='); 

     if (pos > 0) 
     { 
      var key = array[z].substring(0, pos); 
      var value = array[z].substring(pos + 1); 

      if (key=="GUID") { 
       guid = value; 
      } else if (key=="NAME") { 
       name = value; 
      } else if (key=="VCCFG") { 
       if (value != "") { 
        isVersionControlled = true; 
       } 
      } else if (key=="XML") { 
       if (isVersionControlled) { 
        xmlPath = value; 
       } 
      } else if (key=="PARENT") { 
       parentPath = value; 
      } 
     } 
    } 

    // Quick check for target if already exist to speed up process 
    var targetPackage as EA.Package; 
    targetPackage = Repository.GetPackageByGuid(guid); 
    if (targetPackage != null) 
    { 
     // target exists, do not do anything 
     Session.Output("[DEBUG] Target package \"" + name + "\" already exist"); 
     return; 
    } 

    var paths = new Array(); 
    var packages = new Array(paths.Count); 

    for (var i = 0; i < paths.Count; i++) 
    { 
     packages[i] = null; 
    } 

    paths = (parentPath).split("/"); 

    if (paths.Count < 2) 
    { 
     Session.Output("[INFO] Skipped root or level1"); 
     return; 
    } 

    packages[0] = selectRoot(paths[0]); 
    packages[1] = selectPackage(packages[0], paths[1]); 

    if (packages[1] == null) 
    { 
     Session.Output("[ERROR] Cannot find " + paths[0] + "/" + paths[1] + "in Project Browser"); 
     return; 
    } 

    for (var j = 2; j < paths.length; j++) 
    { 
     packages[j] = selectPackage(packages[j - 1], paths[j]); 
     if (packages[j] == null) 
     { 
      Session.Output("[DEBUG] Creating " + packages[j].Name); 

      // create the parent package 
      var parent as EA.Package; 
      parent = Repository.GetPackageByGuid(packages[j-1].PackageGUID); 
      packages[j] = parent.Packages.AddNew(paths[j], ""); 
      packages[j].Update(); 
      parent.Update(); 
      parent.Packages.Refresh(); 
      break; 
     } 
    } 

    // Check if name (package to import) already exist or not 
    var targetPackage = selectPackage(packages[paths.length - 1], name); 

    if (targetPackage == null) 
    { 
     if (xmlPath == "") 
     { 
      Session.Output("[DEBUG] Creating " + name); 

      // The package is not SVN controlled 
      var newPackage as EA.Package; 
      newPackage = packages[paths.length - 1].Packages.AddNew(name,""); 
      Session.Output("New GUID = " + newPackage.PackageGUID); 
      newPackage.Update(); 
      packages[paths.length - 1].Update(); 
      packages[paths.length - 1].Packages.Refresh(); 
     } 
     else 
     { 
      // The package is not SVN controlled 
      Session.Output("[DEBUG] Need to import: " + svnPath + xmlPath); 

      var project as EA.Project; 
      project = Repository.GetProjectInterface; 
      var result; 

      Session.Output("GUID = " + packages[paths.length - 1].PackageGUID); 
      Session.Output("GUID XML = " + project.GUIDtoXML(packages[paths.length - 1].PackageGUID)); 
      Session.Output("XMI file = " + svnPath + xmlPath); 
      result = project.ImportPackageXMI(project.GUIDtoXML(packages[paths.length - 1].PackageGUID), svnPath + xmlPath, 1, 0); 
      Session.Output(result); 

      packages[paths.length - 1].Update(); 
      packages[paths.length - 1].Packages.Refresh(); 
     } 

    } 
    else 
    { 
     // target exists, do not do anything 
     Session.Output("[DEBUG] Target package \"" + name + "\" already exist"); 
    } 
} 

function selectPackage(thePackage, childName) 
{ 
    var childPackage as EA.Package; 
    childPackage = null; 

    if (thePackage == null) 
     return null; 

    for (var i = 0; i < thePackage.Packages.Count; i++) 
    { 
     childPackage = thePackage.Packages.GetAt(i); 

     if (childPackage.Name == childName) 
     { 
      Session.Output("[DEBUG] Found " + childName); 
      return childPackage; 
     } 
    } 

    Session.Output("[DEBUG] Cannot find " + childName); 
    return null; 
} 

function selectRoot(rootName) 
{ 
    for (var y = 0; y < Repository.Models.Count; y++) 
    { 
     root = Repository.Models.GetAt(y); 
     if (root.Name == rootName) 
     { 
      return root; 
     } 
    } 
    return null; 
} 

main();