2013-05-24 3 views
6

Наша команда использует Enterprise Architect version 10 и SVN для репозитория. Поскольку размер файла EAP довольно большой (например, 80 МБ), мы экспортируем каждый пакет в отдельный XMI и сохраняем его в SVN. Сам файл EAP зафиксирован после некоторой вехи. Проблема заключается в синхронизации файла EAP с работой со стороны сотрудника во время разработки, нам нужно импортировать большое количество XMI (например, общее количество может быть 500 файлов).Эффективный способ сделать пакетный импорт XMI в Enterprise Architect

Я знаю, что после обновления файла EAP мы можем использовать Control Package -> Get All Latest. Поэтому эта проблема возникает только при параллельном развитии.

Мы использовали клавиатуры Shorcuts сделать импорт следующим образом:

  1. Ctrl + Alt + I (импорт пакет из XMI файла)
  2. Выберите имя файла для импорта
  3. Alt + I (импорт)
  4. Введите (Да)
  5. Повторите шаг номер 2 до 4, пока модуль не закончил

Но все-таки, импортировать сотни файлов неэффективно.

Я проверил, что пакет управления имеет пакетный импорт/экспорт. Импорт/экспорт партии работает, когда я явно жестко закодировал XMI Filename, но параметры недоступны при использовании управления версиями (параметры пакетного импорта/экспорта серые).

Есть ли лучшие способы синхронизации EAP и XMI файлов?

ответ

4

В EA есть интерфейс scripting. Вы можете автоматизировать импорт, используя это. Я не использовал его, но, вероятно, неплохо.

Я не уверен, что полностью понимаю вашу рабочую среду, но у меня есть некоторые общие моменты, которые могут представлять интерес. Возможно, если вы используете EA по-другому (особенно мой первый пункт ниже), необходимость в импорте пакетов может исчезнуть.

Multiworker

Во-первых, несколько человек могут работать на том же файле EAP в то время. Файл EAP является не более чем файлом базы данных Access, и EA использует блокировку, чтобы остановить одновременное редактирование одного и того же пакета несколькими людьми. Но вы можете с комфортом несколько раз одновременно редактировать разные пакеты в одном файле EAP. Хорошим способом это сделать размещение файла EAP на файловом ресурсе.

Встроено Revision Control

Во-вторых, EA может непосредственно взаимодействовать с SVN (и другими системами контроля версий). См. this.Короче говоря, вы можете настроить свой файл EAP так, чтобы отдельные пакеты (и все ниже) контролировались SVN. Затем вы можете проверить отдельный пакет, отредактировать его, проверить его обратно. Или вы можете проверить всю ветку ниже пакета (включая подпакеты, которые сами контролируются SVN).

Под капотом EA импортирует и экспортирует файлы XMI и проверяет их в SVN и из него, в то время как файл EAP всегда является головной версией. Точно так же, как то, что вы делаете вручную, но автоматизировано. Это имеет смысл, учитывая, что вы можете использовать один единственный файл EAP. Вы должны быть немного осторожны, чтобы вернуться назад - ссылки, происходящие из объектов в старых версиях одного пакета, могут указывать на объекты, которые больше не существуют (но вы можете посмотреть ошибки журнала импорта, чтобы убедиться, что это так). Это требует немного привыкания, но это работает очень хорошо.

Существует также встроенная функциональность базового базового пакета - это может быть все, что вам нужно, и работает очень хорошо, особенно если вы используете один и тот же файл EAP.

Bigger Database Engine

В-третьих, вы не должны иметь файл EAP на всех. База данных модели может быть в любой подходящей системе баз данных (MySQL, SQL Server, Oracle и т. Д.). Таким образом, вы получаете всевозможные варианты масштабирования, как его использовать, что это похоже на WAN/Интернет и т. Д.

Короче говоря, Sparx вполне резонно объяснил, как EA можно использовать в среде с несколькими работниками, и его стоит использовать это.

+0

Okay , позвольте мне проверить скрипты и встроенный контроль версий. – David

+0

Встроенный элемент управления ревизией похож на то, что мы делали прямо сейчас. Нет необходимости проверять пакет на SVN и получать экспорт XMI. Проблема заключается в первом импортировании XMI, потому что каждый член команды использует свой собственный файл EAP. Для сценариев я видел только несколько примеров и объяснений :( – David

+0

Является ли файл EAP каждого члена группы номинально идентичным? Если это так, вы можете просто выбрать тот, который полностью обновлен (или сделать так), привязать его к файловому ресурсу, и тогда каждый может отказаться от своих собственных и начать использовать этот. Затем вы можете настроить этот единственный файл EAP для интеграции с SVN. Вы потеряете непрерывность в своей истории изменений. Короче говоря, я предлагаю одноразовое усилие получить один файл EAP, а затем использовать встроенную автоматизированную интеграцию SVN от EA. – bazza

1

Я создал сценарий EA с помощью JScript для автоматизации

Вот сценарий, чтобы сделать экспорт:

!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(); 

и сценарий, чтобы сделать импорт:

!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(); 
Смежные вопросы