gifts2017

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

Опубликовал Василий Казьмин (awk) в раздел Администрирование - Сервисные утилиты

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

Зачем я написал эту статью? Я в последнее время удалял черновики и наткнулся на http://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 в текст статьи и как прикреплять бесплатные файлы.

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Файл проекта
.xml 0,69Kb
19.01.14
3
.xml 0,69Kb 3 Скачать
Файл свойств
.properties 0,23Kb
19.01.14
3
.properties 0,23Kb 3 Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. q_i 21.01.14 12:24
Интересный вариант использования. Спасибо! Ещё бы поправить орфографию и пунктуацию - вообще было бы супер!
К сожалению я не понял как вставлять файлы xml в текст статьи и как прикреплять бесплатные файлы.

Надо полагать, что те, кто придумывал и реализовывал "старт-монетизацию", даже представить себе не мог что кто-то из авторов захочет прикреплять БЕСПЛАТНЫЕ файлы, поэтому они попросту не предусмотрели такой возможности. Или наборот - предположили, что таковых среди авторов будет подавляющее большинство, а значит они не получат своего процентика, и поэтому не реализовали такую возможность сознательно.
Однако ж положить оба файла в один архив Вы могли бы! ;)
2. Василий Казьмин (awk) 21.01.14 12:40
(1) q_i,
поправить орфографию и пунктуацию
Вроде поправил. Если что word пропустил пишите.
3. Евгений Сосна (pumbaE) 21.01.14 12:59
Вопрос такого плана (если знаешь), как определить переменную получаемую из нескольких источников?
Например, хотелось бы получить в <property> определить переменную bin1C.db.value получаемую из env.bin1Cdbvalue и в случаи отсутствия переменной окружения, только тогда брать из файла свойств или же определять каким либо другим выражением.

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

gradle не пробовал использовать? Имхо в некотором плане проще анализировать результаты от 1С, сейчас то, что бы проанализировать, а успешно ли выполнилась команда, необходимо писать регулярку и анализировать файл результата, иногда не очень удобно.
4. Василий Казьмин (awk) 21.01.14 13:19
(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
5. Василий Казьмин (awk) 21.01.14 13:21
(3) pumbaE, Использовал ruby


		<script language="ruby" classpath="C:\bin\java\jruby-1.7.10\lib\jruby.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
6. Евгений Сосна (pumbaE) 21.01.14 13:51
(4) awk, спасибо. Все руки не доходили.
Я для анализа результатов использую чисто 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"/>
...Показать Скрыть
7. Алексей Лустин (lustin) 21.01.14 17:22
(0)(6)

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

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


8. Василий Казьмин (awk) 21.01.14 17:38
(7) lustin, Может и лучше. Но его еще смотреть надо. Я так понимаю gradle != groovy && gradle =~ groovy
9. Алексей Лустин (lustin) 21.01.14 20:38
(8) awk,

gradle = build DSL on groovy
ну и еще много чего

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

для аналогии по Gradle я советую смотреть Chef и его "рецепты" по приготовлению "блюд"
http://docs.opscode.com/chef/dsl_recipe.html

p.s. конфигурирование на основе xml файлов - сейчас уже вызывает небольшое отвращение.
10. Василий Казьмин (awk) 21.01.14 22:19
(9) lustin, Спасибо. Только я по вашей же рекоммендации добрался до jenkins, а тут еще на-те. :)
11. Алексей Лустин (lustin) 22.01.14 00:24
(10) awk,

Ты представляешь какое "скотство"
это одна и таже команда 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
12. Василий Казьмин (awk) 22.01.14 01:03
(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"
	}
}
...Показать Скрыть
artbear; pumbaE; lustin; +3 Ответить
13. Артур Аюханов (artbear) 23.01.14 18:41
(0) Ты бы еще опубликовал свой тестовый фреймворк, было бы совсем интересно :)
14. Василий Казьмин (awk) 23.01.14 19:04
(13) artbear, От фреймворка одно название. Пара-тройка функций обработка и Вывод:


Z:\Public\Downloads\MSFO>C:\bin\java\gradle-1.10-all\gradle-1.10\bin\gradle 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:\Public\Downloads\MSFO\build.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:\Public\Downloads\MSFO>
...Показать Скрыть
15. Артур Аюханов (artbear) 27.01.14 11:47
(14) вот и выложил бы их. Можно мне в личку aartbear (собачка) gmail.com
16. Василий Казьмин (awk) 27.01.14 12:03
(15) artbear, Откомментирую исходники и пришлю (в течении часа). Правда, у меня под толстый клиент писал на коленке, а о gradle от (7) узнал.
17. Алексей Лустин (lustin) 28.01.14 00:43
(13) ну в идеале нам нужен плагин http://www.gradle.org/docs/current/userguide/custom_plugins.html

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

apply plugin: 'onecmother'


18. Василий Казьмин (awk) 28.01.14 00:56
(17) lustin, Читал. Пока не понял как организовать репозитарий. А имя мне больше G1C нравится.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа