Анатомия Ant или 1С для ленивых администраторв






Пошаговая инструкция создания автоматизации рутинных операций.

Зачем я написал эту статью? Я в последнее время удалял черновики и наткнулся на //infostart.ru/public/181935/. Хотел было ее удалить, да за нее уже проголосовали. Ну раз она кому-то да нужна, по-быстрому написал описание к ней, что к чему и опубликовал. Но радовался я рано. Видать не любит у нас народ поиском пользоваться. Попробую кратко в цикле статей описать те инструменты, которые я использовал для получения результата.

 

Начну с цитаты Википедии:

Apache Ant (англ. ant — муравей и акроним — «Another Neat Tool») — утилита для автоматизации процесса сборки программного продукта. Является платформонезависимым аналогом утилиты make (в качестве «Makefile» применяется «build.xml»).

Ant был создан в рамках проекта Jakarta, сегодня — самостоятельный проект первого уровня Apache Software Foundation.

Первая версия была разработана инженером Sun Microsystems Джеймсом Дэвидсоном (James Davidson (англ.)русск.), который нуждался в утилите, подобной make, разрабатывая первую референтную реализацию J2EE.

Ant, в отличие от другого сборщика проектов Apache Maven, обеспечивает императивную, а не декларативную сборку проекта.

Устанавливается он крайне просто. В Windows(tm) качаем архив, распаковываем и в свойствах системы добавляем к переменной среды %PATH% путь к bin каталогу анта. В linux все еще проще apt-get install(Debian/Ubuntu) ant или yum install ant(Fedora/Red Hat), или pkg-add -r ant(FreeBSD) и т.д.

 

Далее команды с комментариями в  UNIX стиле:

1. mkdir ant_test                     # создаем каталог проекта

2. mkdir .ant                           # создаем каталог для свойств и прочих файлов

3. touch .ant/project.properties # здесь будем хранить значения переменных

4. touch build.xml                    # Файл сборки

5. cat build.xml                       # Добавляем содержание

 

 

6. ant # Запускаем

Buildfile: /home/awk/ant_test/build.xml

BUILD FAILED
Target «help» does not exist in the project «1C».

Total time: 0 seconds

 

Вывод нам рассказал, что в описанном нами проекте по имени 1С не существует цель по умолчанию.

Давайте ее создадим.

И запустим ант

ant

Buildfile: /home/awk/ant_test/build.xml

help:

BUILD SUCCESSFUL
Total time: 0 seconds

 

Здорово, но абсолютно бесполезно.

Что бы что-то получилось в цель надо добавить задачу. Например: сделаем архивацию базы.

Для начала напишем справку

И проверим ее работу:

ant

Buildfile: /home/awk/ant_test/build.xml

help:
     [echo] ant backup — Запуск архивации

BUILD SUCCESSFUL
Total time: 0 seconds

xml узел echo — это задача. Данная задача выводит на экран то, что вы в ней напишете. Теперь давайте напишем саму цель backup

Для начала можно посмотреть справку.

Затем добавим цель и задачу в файл build.xml:

И переменные в файл:.ant/project.properties

echo «bin1C.exec=[путь к программе 1С]» >> .ant/project.properties
echo «bin1C.db.key=[Ключ расположения базы /F или /S]» >> .ant/project.properties
echo «bin1C.db.value=[путь к базе имя файла или сервербаза]» >> .ant/project.properties
echo «bin1C.backup.key=[ключ выгрузки ИБ /DumpIB]» >> .ant/project.properties
echo «bin1C.backup.valuee=[путь куда выгружать]» >> .ant/project.properties

Теперь о том, что мы с вами добавили.

Узел property — здесь мы задали файл где искать файл со свойствами.

Задача exec — здесь мы указали программу для запуска и ее параметры. Атрибут value говорит о том, что это один параметр (даже если он содержит пробелы). А атрибут line — что это несколько параметров разделенных пробелами.

Далее можно запустить ant backup и проверить создался ли файл.

Смысл появился, но все это можно сделать и обычными скриптами. В чем профит? А профит в следующем:

1. Наши настройки действий не зависят от операционной системы. Действия (цели и задачи) настраиваем отдельно от свойств.

2. Любая задача может зависеть от другой задачи.

Давайте посмотрим на примере загрузки конфигурации. Перед ней надо сделать backup — это и реализуем.

 

cat .ant/project.properties                                                  # Файл настроек (моих)
bin1C.exec=/usr/bin/1cv8
bin1C.db.key=/F
bin1C.db.value=/home/awk/runtime-EclipseApplication/t5/db
bin1C.backup.key=/DumpIB
bin1C.backup.value=backup.dt
bin1C.upload.key=/LoadCfg
bin1C.upload.value=1cv8.cf
bin1C.upload.option=/UpdateDBCfg

Что нового мы добавили?

1. Узел upload

2. В узле upload мы сказали что он зависит от backup (depends=»backup»)

3. Заменили ключи выгрузки, на ключи обновления базы.

 

На этом пожалуй на первый раз стоит остановится. А пока можно пойти и посмотреть сколько задач умеет выполнять ант. Они начинаются от файловых операций (создание, удаление, архивирование файлов) и заканчиваются рассылкой почты и отправкой смс.

Напомню задачи берет на себя ант, а цели ему ставите вы.

P.S. К статье прикреплены два созданных файла которые указаны на скриншотах и в тексте. К сожалению я не понял как вставлять файлы xml в текст статьи и как прикреплять бесплатные файлы.

18 Comments

  1. q_i

    Интересный вариант использования. Спасибо! Ещё бы поправить орфографию и пунктуацию — вообще было бы супер!

    К сожалению я не понял как вставлять файлы xml в текст статьи и как прикреплять бесплатные файлы.

    Надо полагать, что те, кто придумывал и реализовывал «старт-монетизацию», даже представить себе не мог что кто-то из авторов захочет прикреплять БЕСПЛАТНЫЕ файлы, поэтому они попросту не предусмотрели такой возможности. Или наборот — предположили, что таковых среди авторов будет подавляющее большинство, а значит они не получат своего процентика, и поэтому не реализовали такую возможность сознательно.

    Однако ж положить оба файла в один архив Вы могли бы! 😉

    Reply
  2. awk

    (1) q_i,

    поправить орфографию и пунктуацию

    Вроде поправил. Если что word пропустил пишите.

    Reply
  3. pumbaE

    Вопрос такого плана (если знаешь), как определить переменную получаемую из нескольких источников?

    Например, хотелось бы получить в <property> определить переменную bin1C.db.value получаемую из env.bin1Cdbvalue и в случаи отсутствия переменной окружения, только тогда брать из файла свойств или же определять каким либо другим выражением.

    Для чего это надо: хотелось бы создать более или менее универсальный build.xml и устанавливать переменные окружения необходимые нам из внешних источников, например из jenkins.

    gradle не пробовал использовать? Имхо в некотором плане проще анализировать результаты от 1С, сейчас то, что бы проанализировать, а успешно ли выполнилась команда, необходимо писать регулярку и анализировать файл результата, иногда не очень удобно.

    Reply
  4. awk

    (3) pumbaE, Легко.

    <condition property=»env.bin1Cdbvalue»>
    <Property name=»bin1C.db.value» value=»${env.bin1Cdbvalue}»/>
    <else>
    <Property name=»bin1C.db.value» value=»blabla»/>
    </else>
    </condition>
    

    http://ant.apache.org/manual/Tasks/condition.html

    Reply
  5. awk

    (3) pumbaE, Использовал ruby

    
    <script language=»ruby» classpath=»C:injavajruby-1.7.10libjruby.jar» src=»result.rb»>
    
    </script>
    
    

    require ‘java’

    factory = javax.xml.parsers.DocumentBuilderFactory.newInstance

    factory.namespace_aware = true # unfortunately, important!

    parser = factory.newDocumentBuilder

    stream = java.io.FileInputStream.new $result

    reader = java.io.InputStreamReader.new stream, ‘cp1251’

    is = org.xml.sax.InputSource.new reader

    document = parser.parse is

    root = document.getDocumentElement()

    tests = root.getElementsByTagName(‘test’)

    0.upto tests.getLength — 1 do |i|

    node = tests.item(i)

    attr = node.getAttributes

    name = attr.getNamedItem ‘name’

    result = node.getFirstChild.getNextSibling.getNextSibling.getNextSibling.getFirstChild.getNodeValue

    puts «#{name.getTextContent} — #{result}»

    if result != ‘true’

    puts node.getFirstChild.getNextSibling.getNextSibling.getNextSibling.getNextSibling.getNextSibling.getFirstChild.getNodeValue

    end

    end

    stream.close

    Показать

    Reply
  6. pumbaE

    (4) спасибо. Все руки не доходили.

    Я для анализа результатов использую чисто ant, читаю файл результат, с помощью регулярки определяю правильный ответ 1С и если что-то не так делаю fail.

    <target name=»dumpcfg»>
    <mkdir dir=»bin»/>
    <exec executable=»${1cbin}»>
    <arg value=»CONFIG»/>
    <arg value=»${ib}»/>
    <arg value=»/N${iblogin}»/>
    <arg value=»/P${ibpassword}»/>
    <arg value=»/ConfigurationRepositoryF${rep}»/>
    <arg value=»/ConfigurationRepositoryN${replogin}»/>
    <arg value=»/ConfigurationRepositoryP${reppassword}»/>
    <arg value=»/ConfigurationRepositoryDumpCfg${builds}/bin/1cv8.cf»/>
    <arg value=»/outoutDumpCfg.txt»/>
    </exec>
    <loadfile property=»checkerror» srcFile=»outDumpCfg.txt» encoding=»cp1251″>
    </loadfile>
    <echo message=»${checkerror}» encoding=»cp866″/>
    <loadfile property=»checkerror» srcFile=»outDumpCfg.txt» encoding=»cp1251″>
    <filterchain>
    <tokenfilter>
    <containsregex pattern=»успешно|success»/>
    </tokenfilter>
    </filterchain>
    </loadfile>
    <fail unless=»checkerror»/>
    </target>
    

    Показать

    т.е. задачи отвечающие за проверку результата такие :

    <loadfile property=»checkerror» srcFile=»outDumpCfg.txt» encoding=»cp1251″>
    <filterchain>
    <tokenfilter>
    <containsregex pattern=»успешно|success»/>
    </tokenfilter>
    </filterchain>
    </loadfile>
    <fail unless=»checkerror»/>
    

    Показать

    Reply
  7. lustin

    (0)(6)

    Может не надо ant ? Да еще и с вызовом ruby

    может http://www.gradle.org/ чуть лучше будет

    Reply
  8. awk

    (7) lustin, Может и лучше. Но его еще смотреть надо. Я так понимаю gradle != groovy && gradle =~ groovy

    Reply
  9. lustin

    (8)

    gradle = build DSL on groovy

    ну и еще много чего

    я не против ant и тем более Maven, так как это 2 очень крутых инструмента. Но как бы так попроще сказать чуть старые (но проверенные временем).

    для аналогии по Gradle я советую смотреть Chef и его «рецепты» по приготовлению «блюд»

    http://docs.opscode.com/chef/dsl_recipe.html

    p.s. конфигурирование на основе xml файлов — сейчас уже вызывает небольшое отвращение.

    Reply
  10. awk

    (9) lustin, Спасибо. Только я по вашей же рекоммендации добрался до jenkins, а тут еще на-те. 🙂

    Reply
  11. lustin

    (10)

    Ты представляешь какое «скотство»

    это одна и таже команда http://www.gradle.org/tooling

    опосредовано

    We are also working with the Jenkins team on a couple of other issues:

    Наткнулся я на данную информацию случайно в процессе автоматизации «билдов» — я думал на основе какого из стандартов работать с 1С

    началось все с вот этого http://stackoverflow.com/questions/5994814/help-evaluating-build-tools

    Что касается ant — это работа не пройдет зря ant.xml напрямую импортируют в Gradle и обратно.

    Так что я не говорю что это другая (новая) технология. Это небольшое уточнение.

    1. Jenkins остается

    2. ant остается

    3. НО вместо build.bat+build.xml мы используем один файл build.gradle

    Reply
  12. awk

    (11) lustin, Я переписал свои тесты с ant на gradle.

    Из минусов gradle:

    1. Работает на 1-2 секунды дольше.

    2. Консоль в M$ удалось победить только chcp 1251

    А так красота и компактность:

    task test4(type:Exec) {
    catalog=»C:/Program Files (x86)/1cv82/»
    version=»8.2.18.82″
    executable(catalog+version+»/bin/1cv8.exe»)
    args «/F», «Z:\v.kazmin\test\msfo\msfo», «/N», «autotest», «/Execute», «Z:\Public\Downloads\MSFO\test_4.epf», «/Out», «log.xml»
    doLast {
    echoLog(«Log.xml»)
    }
    }
    
    void echoLog(String name) {
    
    def f = new File(name)
    def parsedLogXml = (new XmlParser()).parseText(f.getText(‘cp1251′))
    def succ = true
    parsedLogXml.test.each{ test ->
    println «Name : » +  test.@name + «, result : » + test.result.@value
    if(test.result.@value!=’true’) {
    succ = false
    println test.message.text()
    println test.error.text()
    }
    }
    
    if(succ!=true) {
    assert false: «Error test»
    }
    }

    Показать

    Reply
  13. artbear

    (0) Ты бы еще опубликовал свой тестовый фреймворк, было бы совсем интересно 🙂

    Reply
  14. awk

    (13) artbear, От фреймворка одно название. Пара-тройка функций обработка и Вывод:

    Z:PublicDownloadsMSFO>C:injavagradle-1.10-allgradle-1.10ingradle test_6
    :test_6
    Analize file: test_6.xml
    Name : ТестЗаполнениеСчетовПоУмолчанию, result : [true]
    Name : ТестОткрытияДокумента, result : [true]
    Name : ТестКнопкаПодборТЧ1, result : [false]
    Message:
    
    Error:
    {ВнешняяОбработка.ИТПл***.МодульОбъекта(6)}: Количество в таблице
    подбора 0, не совпадает с эталоном 3
    Name : ТестКнопкаПодборТЧ2, result : [false]
    Message:
    
    Error:
    {ВнешняяОбработка.ИТПл***.МодульОбъекта(135)}: Метод объекта не о
    бнаружен (ОткрытьПодборОбъекты***)
    :test_6 FAILED
    
    FAILURE: Build failed with an exception.
    
    * Where:
    Build file ‘Z:PublicDownloadsMSFOuild.gradle’ line: 18
    
    * What went wrong:
    Execution failed for task ‘:test_6’.
    > java.lang.AssertionError: Error test. Expression: false
    
    * Try:
    Run with —stacktrace option to get the stack trace. Run with —info or —debug
    option to get more log output.
    
    BUILD FAILED
    
    Total time: 10.606 secs
    
    Z:PublicDownloadsMSFO>
    

    Показать

    Reply
  15. artbear

    (14) вот и выложил бы их. Можно мне в личку aartbear (собачка) gmail.com

    Reply
  16. awk

    (15) artbear, Откомментирую исходники и пришлю (в течении часа). Правда, у меня под толстый клиент писал на коленке, а о gradle от (7) узнал.

    Reply
  17. lustin

    (13) ну в идеале нам нужен плагин http://www.gradle.org/docs/current/userguide/custom_plugins.html

    gradle — фреймворк, plugin — адаптация gradle для 1С

    apply plugin: ‘onecmother’
    
    

    Reply
  18. awk

    (17) lustin, Читал. Пока не понял как организовать репозитарий. А имя мне больше G1C нравится.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *