суббота, марта 25, 2006

Как обуздать Eclipse. Попытка первая.

Сидя вчера дома больной и опять безуспешно пытаясь добиться от нашего админа дать мне внешний доступ к нашему subversion-репозиторию, а также веселясь другим забавным накладкам, которые в это время происходили на работе, я решил разобраться с Эклипсом. Почему с ним надо разбираться? Все просто. Я хочу управлять сам плагинами Эклипса. Которые составляют конфликтующие конфигурации. Которые капризничают.

Далеко ходить не надо: Flex Builder 2 Beta 2 конфликтует, например, с FDT. Они оба добавляют отдельный content type для .as-файлов в результате чего некоторые горячие клавиши (например, Ctrl+7) в FDT не работают. И это раздражает. Также WTP конфликтует непонятно с чем и в результате корректно не работает. И это тоже раздражает. А человека больного все раздражает сильнее.

Как подобные проблемы решаются? Ну, во-первых, можно для каждого набора плагинов сделать отдельную инсталляцию Эклипса, которыми пользоваться. Недостатки? Полно! Тратится много места на диске (дублируется Эклипс и общие плагины). Сложность обновления как Эклипса, так и плагинов. Ведь обновлять надо в каждом каталоге. Сложность конфигурирования. Ведь замороченно как добавлять, так и удалять плагины чтобы получить нужную конфигурацию (об этом подробнее ниже).

Другой способ упоминал Antares в своем блоге. Это, скажем так, часть нашего решения и потому, во-первых, отошлю вас к первоисточнику и к первоисточнику первоисточника, а, во-вторых, вкратце изложу сам.

Вы организуете папочку для плагинов, которую я храню в Program Files рядом с папкой Eclipse и называю eclipse_config. В ней вы делаете папочку-прототип для всех плагинов и называете ее eclipse. Папочка eclipse должна в себе содержать папочки features и plugins, а также файл с названием .eclipseextension. И файл этот должен содержать в себе следующее:

name=Eclipse Platform
id=org.eclipse.platform
version=3.1.2

Понятно, что это касается версии 3.1.2 как у меня. Если у вас версия другая (версия чего? Гриба, то есть Эклипса), то сами поставите другие цифры.

Теперь для каждого плагина создаете в eclipse_config папку с именем, соотвествующим плагину (например, wtp), в которую копируете прототипную папочку eclipse. И уже внутрь этой папочки копируете ваш плагин.

Данная методика, изложенная в вышеприведенных источниках, предполагает дальнейшее управление плагинами через Help > Software Updates > Manage Configuration. Я легко допускаю, что я туп, но мне этот способ не понравился и вот почему. Во-первых, не всегда можно задисэйблить некоторый плагин. Если от него зависит кто-то еще, то надо сначала его задисэйблить итд. Во-вторых, я так и не смог на своем Эклипсе 3.1.2 включить плагин обратно. Enable на дисэйбленном пути к плагину у меня плагин сам не включает хоть ты тресни! Непредсказуемый результат! Ну и, вдобавок, я не имею конфигураций Эклипса как таковых. Я вынужден каждый раз производить шаманские операции по отключению того, включению этого и так далее. Утомительно, непредсказуемо, требует держать в памяти сочетания конфликтующих плагинов. В общем, не насладился я этим способом.

И я стал искать дальше и нашел приятный линк. И узнал я про способ с линками. И подумалось мне: а что если каждой конфигурации будет соотвествовать свой набор линков. Только вот как этим делом управлять чтобы сохранить и эклипс в единственном экземпляре, и плагины, и запускать легко было, и поддерживать не замороченно? Способов, сразу скажу, очень много. Это и ежу понятно. Я выбрал близкий себе способ, о котором уже однажды рассказывал, - Apache Ant.

Итак, что я хочу? Я хочу получить билд-файл, который бы имел цели запуска конфигураций плагинов, которые я ему определю. И вот тут начинается самая трудоемкая часть задачи. Сразу скажу, что поддерживать это дело будет гораздо легче. Тем более, что ant-редактор в Эклипсе очень хорош. И сам ant-скрипт это простой и естественный xml-диалект.

Приступим. Если вы не знакомы с Ant'ом - идите пока читать статью и устанавливать рабочую среду. Сразу скажу, что вам тут, по сути, понадобится только сам ant (и, понятно, jre, которая у вас, судя по тому, что вы работаете с Эклипсом, есть. Также по этой причине у вас есть и Ant, но в плагинах. Неплохо бы иметь и standalone-установку). Пока вы изучаете, я тем временем создам в папке eclipse_config папку links_store, куда сложу все мои link-файлы. Линк-файл может, например, называться asdt.link и содержать в себе строку:

path=C:\\Program Files\\eclipse_config\\ASDT\\

В корне моей папки eclipse_config я создаю билд-файл, который называю build.xml. Также создаю файл local.properties для локальных индивидуальных настроек. Приведу пример моего билд-файла:


<?xml version="1.0"?>
<!-- ======================================================================
24.03.2006 15:39:09

eclipse.config
Build file for eclipse configs launching

Constantiner
====================================================================== -->
<project name="eclipse.config" default="run.all.plugins" basedir=".">
<description>
Build file for eclipse configs launching
</description>

<!-- Define properties to override in local.properties file -->
<property file="local.properties" />
<!-- Define Eclipse folder (with eclipse executable and features/plugins folder). Override it in local.properties -->
<property name="eclipse.dir" location="."/>
<!-- Path to Eclipse executable -->
<property name="eclipse.path" location="${eclipse.dir}/eclipse.exe"/>

<!-- Folder to store all plugins links (in plugins configuration folder outside eclipse folder) -->
<property name="links.store" location="links_store/"/>
<!-- Target for links copying (in eclipse folder) -->
<property name="links" location="${eclipse.dir}/links/"/>

<!-- Define properties for link files names -->
<property name="all_the_news.link" value="all_the_news.link" />
<property name="asdt.link" value="asdt.link" />
<property name="CFEclipse.link" value="CFEclipse.link" />
<property name="eclipse.colorer.link" value="eclipse.colorer.link" />
<property name="flex.link" value="flex.link" />
<property name="gef.link" value="gef.link" />
<property name="misc.link" value="misc.link" />
<property name="PHPEclipse.link" value="PHPEclipse.link" />
<property name="subclipse.link" value="subclipse.link" />
<property name="uml2.link" value="uml2.link" />
<property name="ve.link" value="ve.link" />
<property name="winamp.link" value="winamp.link" />
<property name="wtp.link" value="wtp.link" />
<property name="XSD-SDO-EMF.link" value="XSD-SDO-EMF.link" />
<property name="PHPIDE.link" value="PHPIDE.link" />

<!-- Section defines pluginsets for every configuration -->
<fileset dir="${links.store}" id="core">
<patternset id="core.pattern">
<include name="${misc.link}"/>
<include name="${eclipse.colorer.link}"/>
<include name="${gef.link}"/>
<include name="${uml2.link}"/>
<include name="${winamp.link}"/>
<include name="${XSD-SDO-EMF.link}"/>
<include name="${subclipse.link}"/>
<include name="${ve.link}"/>
<include name="${all_the_news.link}"/>
</patternset>
</fileset>

<fileset dir="${links.store}" id="all">
<patternset id="all.pattern">
<patternset refid="core.pattern" />
<include name="${asdt.link}"/>
<include name="${CFEclipse.link}"/>
<include name="${flex.link}" />
<include name="${PHPEclipse.link}"/>
<include name="${wtp.link}"/>
<include name="${PHPIDE.link}"/>
</patternset>
</fileset>

<fileset dir="${links.store}" id="cold.fusion">
<patternset id="cold.fusion.pattern">
<patternset refid="core.pattern" />
<include name="${CFEclipse.link}"/>
</patternset>
</fileset>

<fileset dir="${links.store}" id="php">
<patternset id="php.pattern">
<patternset refid="core.pattern" />
<include name="${PHPEclipse.link}"/>
</patternset>
</fileset>

<fileset dir="${links.store}" id="flash.asdt">
<patternset id="flash.asdt.pattern">
<patternset refid="core.pattern" />
<include name="${asdt.link}"/>
</patternset>
</fileset>

<fileset dir="${links.store}" id="flex">
<patternset id="flex.pattern">
<patternset refid="core.pattern" />
<include name="${flex.link}"/>
</patternset>
</fileset>

<fileset dir="${links.store}" id="wtp">
<patternset id="wtp.pattern">
<patternset refid="core.pattern" />
<include name="${wtp.link}"/>
</patternset>
</fileset>

<fileset dir="${links.store}" id="php.ide">
<patternset id="php.ide.pattern">
<patternset refid="core.pattern" />
<include name="${wtp.link}"/>
<include name="${PHPIDE.link}"/>
</patternset>
</fileset>
<!-- End of pluginsets section -->

<!-- =================================
target: run.all.plugins
================================= -->
<target name="run.all.plugins" depends="clean,init,install.all,run.eclipse" description="--> Runs with all plugins">

</target>

<!-- - - - - - - - - - - - - - - - - -
target: install.all
- - - - - - - - - - - - - - - - - -->
<target name="install.all">
<install.links links.id="all" />
</target>

<!-- =================================
target: run.php.ide
================================= -->
<target name="run.php.ide" depends="clean,init,install.php.ide,run.eclipse" description="--> Runs for PHP development with Zend PHP IDE">

</target>

<!-- - - - - - - - - - - - - - - - - -
target: install.php.ide
- - - - - - - - - - - - - - - - - -->
<target name="install.php.ide">
<install.links links.id="php.ide" />
</target>

<!-- =================================
target: run.cold.fusion
================================= -->
<target name="run.cold.fusion" depends="clean,init,install.cold.fusion,run.eclipse" description="--> Runs for ColdFusion development with CFclipse">

</target>

<!-- - - - - - - - - - - - - - - - - -
target: install.cold.fusion
- - - - - - - - - - - - - - - - - -->
<target name="install.cold.fusion">
<install.links links.id="cold.fusion" />
</target>

<!-- =================================
target: run.php
================================= -->
<target name="run.php" depends="clean,init,install.php,run.eclipse" description="--> Runs for PHP development with PHPEclipse">

</target>

<!-- - - - - - - - - - - - - - - - - -
target: install.php
- - - - - - - - - - - - - - - - - -->
<target name="install.php">
<install.links links.id="php" />
</target>

<!-- =================================
target: run.flash.asdt
================================= -->
<target name="run.flash.asdt" depends="clean,init,install.flash.asdt,run.eclipse" description="--> Runs for Flash development with ASDT">

</target>

<!-- - - - - - - - - - - - - - - - - -
target: install.flash.asdt
- - - - - - - - - - - - - - - - - -->
<target name="install.flash.asdt">
<install.links links.id="flash.asdt" />
</target>

<!-- =================================
target: run.flex
================================= -->
<target name="run.flex" depends="clean,init,install.flex,run.eclipse" description="--> Runs for Flex development with Flex Builder 2">

</target>

<!-- - - - - - - - - - - - - - - - - -
target: install.flex
- - - - - - - - - - - - - - - - - -->
<target name="install.flex">
<install.links links.id="flex" />
</target>

<!-- =================================
target: run.wtp
================================= -->
<target name="run.wtp" depends="clean,init,install.wtp,run.eclipse" description="--> Runs for J2EE development with WTP">

</target>

<!-- - - - - - - - - - - - - - - - - -
target: install.wtp
- - - - - - - - - - - - - - - - - -->
<target name="install.wtp">
<install.links links.id="wtp" />
</target>

<!-- - - - - - - - - - - - - - - - - -
target: clean
Clear links folder for configuration launching
- - - - - - - - - - - - - - - - - -->
<target name="clean">
<delete>
<fileset dir="${links}" includes="**/*.link"></fileset>
</delete>
</target>

<!-- - - - - - - - - - - - - - - - - -
target: init
Creates links folder (if not exists)
- - - - - - - - - - - - - - - - - -->
<target name="init">
<mkdir dir="${links}"/>
</target>

<!-- - - - - - - - - - - - - - - - - -
target: run.eclipse
Runs eclipse with workbench parameter.
- - - - - - - - - - - - - - - - - -->
<target name="run.eclipse" if="workbench" depends="run.eclipse.without.workbench">
<exec executable="${eclipse.path}" spawn="true">
<arg line="-data" />
<arg value="${workbench}" />
<arg line="-clean" />
<arg line="-refresh" />
<arg line="-nl en_US" />
</exec>
</target>

<!-- - - - - - - - - - - - - - - - - -
target: run.eclipse.without.workbench
- - - - - - - - - - - - - - - - - -->
<target name="run.eclipse.without.workbench" unless="workbench">
<exec executable="${eclipse.path}" spawn="true">
<arg line="-clean" />
<arg line="-refresh" />
<arg line="-nl en_US" />
</exec>
</target>

<!-- = = = = = = = = = = = = = = = = =
macrodef: install.links
= = = = = = = = = = = = = = = = = -->
<macrodef name="install.links">
<attribute name="links.id" />
<sequential>
<copy todir="${links}" >
<fileset refid="@{links.id}" />
</copy>
</sequential>
</macrodef>
</project>

Данный файл достаточно объемен, но, в общем-то, прост. Тем более что содержит комментарии на корявом английском. Заслуживает внимания секция перечисления всех интересующих нас линков, секция определения набора линков для каждой конфигурации, а также собственно цели запуска конфигураций. Заслуживает интереса наличие секции core, в которой я перечислил плагины, доступные в каждой конфигурации. Также обратите внимание на приватные цели run.eclipse и run.eclipse.without.workbench. Что это значит? Это значит, что вы можете определить свойство workbench, при наличии которого ваша конфигурация запустится в нужном вам workbench'е. Также при запуске Эклипса я добавил опции -clean (очищает кэш зависимостей плагинов), -refresh (обновляет проекты при запуске), а также -nl en_US (запускает Эклипс как если бы вы находились в США - необходимость этого описана в одном из моих постов). Свойство workbench можно задать двумя способами. Во-первых, в файле local.properties. При этом оно будет общим для всех конфигураций, что нам не очень-то интересно. Второй способ я опишу ниже, а сейчас приведу мой вариант файла local.properties:


eclipse.dir = C:\\Program Files\\Eclipse\\
#links.store = links_store

Здесь я просто задаю мой каталог с установкой Eclipse SDK. Там же можно задать многие другие свойства.

Если мы запустим теперь наш билд-файл в режиме помощи:

ant -projecthelp

То увидим все наши доступные публичные цели:

Buildfile: build.xml

Build file for eclipse configs launching

Main targets:

run.all.plugins --> Runs with all plugins
run.cold.fusion --> Runs for ColdFusion development with CFclipse
run.flash.asdt --> Runs for Flash development with ASDT
run.flex --> Runs for Flex development with Flex Builder 2
run.php --> Runs for PHP development with PHPEclipse
run.php.ide --> Runs for PHP development with Zend PHP IDE
run.wtp --> Runs for J2EE development with WTP

Default target: run.all.plugins

Цель run.php.ide меня вчера попросил добавить Михаил «Antares» Клишин с целью проверить совместимость текущей версии PHP IDE (0.5) с WTP 1.0 и Eclipse 3.1.2. Легко - сказал я. Я сделал папку Zend PHPIDE в моей eclipse_config, куда по описанным выше правилам скопировал данный плагин. В билд-файле я добавил свойство с именем линк-файла плагина (который тоже сделал в links_store):

<property name="PHPIDE.link" value="PHPIDE.link" />

Далее добавил набор линк-файлов данной конфигурации (включая wtp):

<fileset dir="${links.store}" id="php.ide">
<patternset id="php.ide.pattern">
<patternset refid="core.pattern" />
<include name="${wtp.link}"/>
<include name="${PHPIDE.link}"/>
</patternset>
</fileset>

И, собственно, сами цели, копирующие линки в папку Эклипса и запускающие ее:

<!-- ================================= 
target: run.php.ide
================================= -->
<target name="run.php.ide" depends="clean,init,install.php.ide,run.eclipse" description="--> Runs for PHP development with Zend PHP IDE">

</target>

<!-- - - - - - - - - - - - - - - - - -
target: install.php.ide
- - - - - - - - - - - - - - - - - -->
<target name="install.php.ide">
<install.links links.id="php.ide" />
</target>

Это заняло у меня совсем немного времени, зато в результате я узнал, что данная конфигурация вполне рабочая.

Как запускать эту конфигурацию? Просто наберите в командной строке:

ant run.php.ide

Эклипс запустится в данной конфигурации в последнем использовавшемся workbench'е.

Но тут есть два недостатка: во-первых, неудобно каждый раз набирать такие команды, а, во-вторых, хотелось бы для разных конфигураций задавать разные workbench'и (для flash-разработки - один, для php - другой). Эта проблема запросто решается с помощью bat-файлов на наиболее употребимые варианты. Например, для запуска PHP IDE мы делаем php.ide.bat, лежащий рядом с build.xml, который имеет следующий вид:

ant run.php.ide -Dworkbench=E:\Constantiner\!Projects\php_development

Поясню, что с помощью конструкции -Dproperty=value мы можем устанавливать значения свойств для Ant'а.

Я пошел дальше. Я сделал себе несколько bat-файлов, а наиболее употребимые кинул на рабочий стол, поменял им иконки на нужные мне и с того имею плизир.

Я согласен с Мартином Фаулером, что таким ленивым людям, как он и я, необходимо немало потрудиться чтобы сократить работу в будущем.

Ну а теперь перечислю достоинства и недостатки данного способа. Достоинства:


  • Мы имеем по одному экземпляру Eclipse SDK и плагинов, что экономит место на диске.

  • Мы в любой момент можем сменить версию как SDK, так и плагинов без необходимости переставлять и чистить все.

  • Мы запускаем Eclipse с ограниченным набором плагинов, что так или иначе увеличивает производительность.

  • Мы просто управляем процессом конфигурирования среды Eclipse.

  • Мы избавляемся от конфликта плагинов.

  • Мы получаем удовлетворение от проделанных изысканий :)


Недостатки:


  • Первоначальная организация рабочей среды трудоемка, требует множества различных действий и навыков. То есть этот способ расчитан на профессионалов.

  • Возможны проблемы с восстановлением рабочей перспективы если в одном workbench'е запускать разные конфигурации. Можно забить. Но, возможно, кто-то предложит способ избежать этого.

  • Возможные проблемы с установкой плагинов. Это касается плагинов, устанавливаемых через update site и тех, которые устанавливаются инсталляторами (типа Flex Builder 2). Эти проблемы обходятся, но не очень изящно. Хотелось бы иметь простое решение.


Ну вот, собственно, и все, о чем я хотел вам поведать. Спасибо за внимание. Пишите свои пожелания, вопросы, замечания. Моя методика не претендует на полноту, идеальность и общеприменимость. Но если кого-то она наведет на гениальные идеи... То делитесь! :)

Комментариев 11:

Anonymous Анонимный сообщает:

Константин подскажи пожалуйста как добавить кодировки в eclipse

Нужно файлы редактироать и просматривать к примеру в koi-8 cp-1251^ а у меня их нет в наборе eclipse как их туда добавитьт не могу найти (antohach[]mail.ru)

спасибо

29 марта, 2006 20:11  
Blogger Constantiner сообщает:

2Anonimous
Если честно, я не знаком с такими тонкостями Эклипса, ибо работаю преимущественно в юникоде. Думаю, что надо либо изучить доку (help), либо поискать какой-нибудь плагин. Готового решения у меня нет.

29 марта, 2006 20:34  
Anonymous Анонимный сообщает:

А в каких местах искать?

на eclipse.org ни чего не нашел :(

http://www.phpeclipse.de еще не весь излазил

может подскажешь форум какой хороший?

спасиб

30 марта, 2006 13:56  
Blogger Constantiner сообщает:

2Anon
http://www.eclipseplugincentral.com/
http://eclipse-plugins.info/

30 марта, 2006 20:07  
Anonymous Анонимный сообщает:

это в течении для облазил не нащел http://www.eclipseplugincentral.com/
второй почти теже плагины выдает

на http://www.phpeclipse.de в форуме нашел похожий овпрос но без ответа, на мой тоже пока ни кто не ответил.

Komodo и Jide на много проще, но там не забыли вставить такую штуку как каботать с файоами в любой кодировке.Понятно что юникод решает все проблемы, но вот тогда проекты заказчиков нужно все разом переводить на юникод, да еще конвертнуть данные из базы :(

30 марта, 2006 23:12  
Blogger Constantiner сообщает:

2Anonim
Ну можно написать антовскую задачу, которая переконвертит проект в другую кодировку :)

31 марта, 2006 11:49  
Anonymous Анонимный сообщает:

Тогда нгужно будет научить ант что бы он перекодировал проект еще и на компьютеррах других участников проекта :)

02 апреля, 2006 17:16  
Blogger Constantiner сообщает:

2Anon
Ну в этом как раз сложности нет. Ant-овские задачи при правильном написании применимы к любому компьютеру.

02 апреля, 2006 17:33  
Anonymous Анонимный сообщает:

Только вот у этих людей его нет :)

Подстраиваться под большенство не так уж и плохо в проектах :/

03 апреля, 2006 18:12  
Blogger Andrew сообщает:

Укажи просто windows-1251 или cp1251

04 ноября, 2006 20:59  
Blogger Andrew сообщает:

в смысле -- руками впиши

04 ноября, 2006 21:00  

Отправить комментарий

Ссылки на пост:

Создать ссылку

Вернуться на главную