Подтвердить что ты не робот

Как вернуть значение из финской цели?

Я хотел бы иметь такую ​​задачу foreach, которая выполняет итерацию по всем файлам/каталогам в каталоге "A" -

<foreach param="dirname" absparam="absname" target="subtask">
  <fileset dir="${dir.destination}/${dir.subdir}/">
    <type type="file" />
    </fileset>
</foreach>

Целевая "подзадача" должна проверить, существует ли копия файла/папки в другом каталоге "B" (я сравниваю каталоги A и B в основном) и возвращать одно из следующих, если это не так -

  • флаг.
  • имя файла.

Ниже приведен некоторый код для справки -

<target name="subtask">
    <if>
        <filesmatch file1="${file1}" file2="${file2}"/>
        <then>
            Return false. But how?
        </then>
        <else>
            Return true of name of the file. How?
        </else>
    </if>
</target>

Примечание. Это нормально, если это можно сделать без вызова цели. Я не уверен, что логика может быть помещена внутри самой яхты. Не удалось найти такую ​​вещь в документации phing.

В принципе, я должен иметь список имен файлов, которых нет в каталоге B, к концу цикла.

Вы также можете прочитать этот вопрос, если вы можете дать некоторые указатели, чтобы решить проблему другим способом.

Обновление

Перефразируя этот вопрос, поскольку я чувствую, что описание проблемы неясно. phing documentation говорит, что цель не имеет возвращаемого значения -

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

Я не понимаю, почему это так. С этой щедростью я хотел бы знать, есть ли какое-то решение для меня, кроме необходимости определять мои собственные пользовательские задачи в PHP, а затем задавать свойства -

$this->getProject()->setNewProperty('modifiedElements', implode("\n\n",$modifiedElementsArray));

к которому можно получить доступ в файле сборки

У меня есть цель, которая проверяет, имеет ли моя база производственного кода какие-либо отличия от ожидаемой версии git -

<target name="compare_prod_with_expected_revision">
        <input propertyname="box.git_version">
            Enter git version of the production codebase:
        </input>
        <exec command="git reset --hard ${box.git_version}" dir="${dir.scratchpad}" />
        <!-- Scratchpad brought to revision ${box.git_version} -->

        <echo>Verifying whether production is at revision ${box.git_version}..</echo>
        <exec command="diff -arq --exclude='.git' ${dir.scratchpad}/${dir.subdir} ${dir.destination}/${dir.subdir}" outputProperty="diffList"/><!-- #TODO ignore.swp files in this step. Diff says .swp files present in production code. But doing ls -a there does not show the same. -->
        <php function="strlen" returnProperty="productionDeviationFromExpectedBranch"><!-- #TODO - find how to not show this step during build process. Put it in a target and set hidden="true" -->
            <param value="${diffList}"/>
        </php>
        <if>
            <equals arg1="${productionDeviationFromExpectedBranch}" arg2="0" />
            <then>
                <echo>Verified production is at revision ${box.git_version}</echo>
            </then>
            <else>
                <echo>Differences -  </echo>
                <echo>${diffList}</echo>
            </else>
        </if>
    </target>

Теперь я хочу phingcall эту цель и хотел бы получить доступ к некоторому свойству, установленному им.

4b9b3361

Ответ 1

Я думаю, что я понял ваши цели, и в то же время я чувствую, что вы выбрали не оптимальный инструмент для этого.

Как вы упомянули в своем вопросе, официальная документация по phing ясно о задачах (целях):

Целями являются коллекции компонентов проекта (но не другие цели), которым назначено уникальное имя в рамках своего проекта. Цель обычно выполняет определенную задачу - или вызывает другие цели, которые выполняют определенные задачи, и поэтому цель немного похожа на функцию (но у цели нет значения возврата).

Цели должны быть компонентами вашего приложения, которые выполняют конкретную задачу, атомную задачу. Это может быть задача инициализации, выборка конфигурации, этап компиляции, подготовка и демпинг активов, задача развертывания, задача очистки и т.д. Нет "результата", возвращаемого целевым объектом в стандартном смысле, но результат выполнения задачи это успех самого исполнения: успех или неудача.

Не нужно пытаться вложить слишком много логики в такие цели проекта, поскольку не предназначено выполнять сложные вычисления, делать тяжелые логические решения и т.д. Я имею в виду, что Phing может это сделать, такие вещи возможны, но эта установка будет громоздкой, нечитабельной и трудно масштабируемой/перефакторной.

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

На основе проектов, с которыми я работал, наиболее важными целями, вероятно, были этап инициализации и выборка настроек. Вот пример, чтобы понять, что он может содержать, я взял его из реального проекта:

<target name="init_configuration">
    <echo msg="Define initial configuration for the deployment..." />
    <if>
        <not>
            <isset property="host" />
        </not>
        <then>
            <property name="host" value="dev" override="true" />
            <echo message="The value of hostname has been set to ${host}" />
        </then>
        <else>
            <echo message="The value of hostname is ${host}" />
        </else>
    </if>
    <if>
        <not>
            <isset property="version" />
        </not>
        <then>
            <property name="version" value="1.0.0" override="true" />
            <echo message="The value of version has been set to ${version}" />
        </then>
        <else>
            <echo message="The value of version is ${version}" />
        </else>
    </if>

    <property name="host_credital_file" value="config/hosts/${host}.properties" />
    <property file="${host_credital_file}" />
    <available file="${host_credital_file}" property="hostfilefound" value="true"/>
    <fail unless="hostfilefound" message="Missing Hostfile configuration file (${host_credital_file})!" />

    <echo msg="Configuration is done" />
</target>

Другие цели были чрезвычайно упрощенными, они обычно - длиной 1-5 строк, и выполняют небольшую задачу, небольшую задачу. Это было бы, вероятно, лучшей рекомендацией при работе с Phing.


Логика, которую вы пытаетесь надеть на плечи Phing, возможна, но будет чрезвычайно громоздкой.

Рассмотрим вопрос: насколько быстрее, проще и понятнее то же самое можно сделать с помощью простого bash script в вашем примере. Или даже написать небольшую утилиту CLI в PHP, которая сделает работу элегантно и быстро. После этого в Phing вы оставите параметрическую цель, которая выполнит эту "ревизию diff script" из CLI.

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

Как обходной путь, для более сложных вещей лучше комбинировать Phing с чем-то специализированным: bash scripting, PHP CLI, nodeJS (+ Grunt, Gulp и т.д.)... и просто добавить вызовы целевых объектов Phing позже.

Ответ 2

Целевая "подзадача" должна проверить, существует ли аналог файла/папки в другом каталоге "B" (я сравниваю в основном каталоги A и B), и вернуть одно из следующего, если этого не происходит -

  • флаг.
  • имя файла.

Вы можете сравнить две директории, не используя задачу foreach например:

<project name="Phing Build Test" default="print-missing" basedir=".">
    <resolvepath propertyName="dir.a" path="path/to/dir/a"/>
    <resolvepath propertyName="dir.b" path="path/to/dir/b"/>
    <target name="print-missing">
        <apply executable="echo" failonerror="false" returnProperty="files.found" outputProperty="missing">
            <srcfile/>
            <fileset id="srcfiles" dir="${dir.a}" includes="*">
                <present present="srconly" targetdir="${dir.b}"/>
            </fileset>
        </apply>

        <if>
            <equals arg1="${files.found}" arg2="0"/>
            <then>
                <echo msg="${missing}"/>
            </then>
            <else>
                <fail message="Files need to be checked in"/>
            </else>
        </if>
    </target>
</project>