Вот странная проблема, связанная с комбинацией функций «define» и «include», которые предоставляет препроцессор CC.NET. Мы используем CCNet 1.4.4.83, а наш файл ccnet.config
структурирован и разбит, чтобы наилучшим образом использовать общие блоки элементов, хранящиеся в подфайлах, которые включены в основной файл конфигурации; мы также отщепляемся определения основного проекта в свои собственных заголовочные файлы тоже, оставив ccnet.config
по существу серии из включают в себя, таким образом:CruiseControl.NET Preprocessor 'include' Anomaly
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<!-- Configuration root folder - defined so we can use it as a symbol instead of using slightly confusing relative paths -->
<cb:define ccConfigRootFolder="C:\CruiseControl.NET\Config"/>
<!-- Globals - standard or shared build elements common to all projects -->
<cb:include href="$(ccConfigRootFolder)\Globals\globals.xml" xmlns:cb="urn:ccnet.config.builder"/>
<!-- CruiseControl.NET Configuration - refresh configuration if changed -->
<cb:include href="$(ccConfigRootFolder)\CCNet Configuration\ccnet_configuration.xml" xmlns:cb="urn:ccnet.config.builder"/>
<!-- Project #1 -->
<cb:include href="$(ccConfigRootFolder)\Project1\project1.xml" xmlns:cb="urn:ccnet.config.builder"/>
<!-- Project #2 -->
<cb:include href="$(ccConfigRootFolder)\Project2\project2.xml" xmlns:cb="urn:ccnet.config.builder"/>
</cruisecontrol>
Это работает лакомство - препроцессор правильно включает и разбирает <define>
элементов в globals.xml
(и рекурсивно анализирует дальнейшие файлы, включенные также с globals.xml
), и проекты, включенные впоследствии (которые содержат ссылки на эти определенные элементы), анализируются правильно.
Для дальнейшего уточнения ccnet.config
в попытке уменьшить вероятность ошибок, нарушающих процесс сборки, мы изменили его выглядеть следующим образом:
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<!-- Configuration root folder -->
<cb:define ccConfigRootFolder="C:\CruiseControl.NET\Config"/>
<!-- Project 'include' element definition -->
<cb:define name="ProjectInclude">
<cb:include href="$(ccConfigRootFolder)$(ccIncludePath)" xmlns:cb="urn:ccnet.config.builder"/>
</cb:define>
<!-- Include common gobal elements -->
<cb:ProjectInclude ccIncludePath="\Globals\globals.xml"/>
<!-- Project #1 -->
<cb:ProjectInclude ccIncludePath="\Project1\project1.xml"/>
<!-- Project #2 -->
<cb:ProjectInclude ccIncludePath="\Project2\project2.xml"/>
</cruisecontrol>
Как вы можете видеть, мы внедренный общее, повторяющееся, часть определения 'include' в его собственном определенном блоке, а затем использовать это, чтобы каждый из них включал использование пути в качестве параметра - идея заключается в том, что будущие модификаторы файла не будут иметь возможности случайно забыть что-то на их новом включенном проектные линии (такие как препроцессор URN); до тех пор, пока их xml-файл существует, и они получают путь к нему вправо, остальное позаботится об общем определении include.
Единственная проблема заключается в том, что это не сработает - по какой-то причине файл globals.xml
не обрабатывается должным образом (или, возможно, даже включен), потому что проекты, включенные после него, жалуются на отсутствие определенных элементов; то есть ссылки на элементы, определенные в файле globals, по-видимому, не были «зарегистрированы», потому что проекты не распознают их.
Мы попытались вынуть вложенные входящие из globals.xml
и включить их непосредственно на верхнем уровне, но безрезультатно. Комментирование первой справочной ссылки на проблему в проекте просто заставляет Validator жаловаться на следующую, с сообщением «Предварительная обработка не удалось загрузить XML: Ссылка на неизвестный символ XXXXX». Однако, если мы вставляем тело globals.xml
в ccnet.config
, это работает. Необычно, хотя это может звучать, как будто препроцессор полностью не смог разобрать globals.xml
, но потом радостно пережевывал файлы проекта, а затем терпел неудачу, потому что глобальные ссылки не определены.
Валидатор терпит неудачу, если это так, однако. И, конечно, потому что он не может правильно проанализировать XML проекта, мы ничего не получаем на вкладках «Оригинал» или «Обработано». Служба CruiseControl.NET сама не запускается с бесполезным исключением:
Обслуживание не может быть запущено. System.Runtime.Serialization.SerializationException: Тип '' ThoughtWorks.CruiseControl.Core.Config.Preprocessor.EvaluationException в Ассамблее «ThoughtWorks.CruiseControl.Core, Version = 1.4.4.83, культура = нейтральной, PublicKeyToken = null 'не помечен как сериализуемым. Трассировка стека сервера: System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize (Объект OBJ, ISurrogateSelector surrogateSelector, StreamingContext контекст, SerObjectInfoInit serObjectInfoInit, IFormatterConverter конвертер, ObjectWriter objectWriter) на System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize (Object OBJ, ISurrogateSelector surrogateSelector, StreamingContext контекст, serObjectInfoInit serObjectInfoInit, IFormatterConverter конвертер, ObjectWriter objectWriter) на System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize (Объект графа, H eader [] inHeaders, __BinaryWriter serWriter, Boolean fCheck) в System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Ser ...
Вся документация говорит, что это должно работать, и нет никакого упоминания о какой-либо несовместимость или несогласованность при использовании «include» внутри «define». Поэтому я в тупике, и любое понимание или совет на этом этапе будут высоко оценены.
Хм - этот вопрос (CCNET-1865) относится к CCNet 1.5.0 RC1, в частности недавней сборки 1.5.x (т.е. это не было проблемой до этой недавней сборки). Так ли решение для CCNET-1865 затрагивает гораздо более глубокую проблему, существовавшую с 1.4.4.83 (версия, которую я запускаю), и которая недавно усугубляется в 1.5.x сборке? Что еще более важно, заявляете ли вы, что для того, чтобы механизм «include» работал, как ожидалось, мне нужно будет обновить мою установку 1.4.4.83 до 1.5 RC? Не будет регрессионного патча для релиза 1.4.4.83? –
Hi 1.4.4 был отменен, поэтому никаких исправлений не будет. Можете ли вы отправить мне свои файлы конфигурации, и я проверю, правильно ли он обрабатывает 1.5. Почему вы не хотите обновлять до 1.5? у него есть много новых функций, и в текущей магистрали (v1.6) у нас есть другой движок для предварительного процессора (на основе LINQ), поэтому обновление ветки 1.4.4 будет даже меньше вероятно. – Williams
Ум, почему 1.4.4 прекращено ?? Это последний релиз «производства» - у 1.5 есть только релизы CTP и RC1, и поэтому он еще не вышел в финальный релиз RTM! Именно поэтому я не модернизирую свои 1.4.4 серверы до 1.5, потому что у меня около 50 или около того проектов, построенных на 1.4.4, и кучка разработчиков, которые будут висеть у меня на ногах из окна верхнего этажа, если я просто плюнули на CTP или RC1 сборку CC.Net на их CI серверы! Неверная конфигурация - это то, что я написал в вопросе - «include» внутри «define» анализируется аномально. –