如何从phing目标返回值?

时间:2016-04-14 09:17:12

标签: phing

我希望有一个像这样的foreach任务,它遍历目录中的所有文件/目录" A" -

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

目标&#34;子任务&#34;应该检查文件/文件夹的对应物是否存在于另一个目录中&#34; B&#34; (我基本上比较了目录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>

注意 - 如果可以在不调用目标的情况下完成此操作,则可以。我不确定逻辑是否适合在foreachtask本身。在phing documentation

中找不到任何此类内容

基本上,我应该在循环结束时获得目录B中不存在的文件名列表。

如果您能提供一些指示以其他方式解决问题,您也可以read this question

更新

改述这个问题,因为我觉得问题描述不清楚。 phing documentation表示,目标没有返回值 -

  

目标是项目组件的集合(但不是其他目标)   在项目中分配了唯一的名称。目标   通常执行特定任务 - 或调用其他目标   执行特定任务 - 因此目标有点像   function(但目标没有返回值)。

我不明白为什么会这样设计。有了这个赏金,我想知道除了必须在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此目标,并希望访问由其设置的某些属性。

3 个答案:

答案 0 :(得分:5)

我认为我明白了你的目的,同时我觉得你选择的不是这样做的最佳工具。

正如您在问题中提到的,关于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脚本可以更快,更容易,更可读。甚至可以在PHP 中编写小型 CLI实用程序,这将优雅而快速地完成工作。之后在Phing中,您将离开参数目标,该目标将从CLI执行此“修订差异脚本”。

Phing是设计用途的绝佳工具,但它不能成为各种用途的最佳选择。只是不要把责任和逻辑放在其中。

作为解决方法,对于更复杂的事情最好将Phing与专门的东西结合起来:bash脚本,PHP CLI,nodeJS(+ Grunt,Gulp等)......只是稍后添加Phing目标的调用

答案 1 :(得分:1)

这是我设法使目标像功能一样的方式:

<target name="-console-cmd-return-property" hidden="true">
    <exec command="${command}" checkreturn="${checkreturn}" logoutput="${logoutput}" outputProperty="${outputProperty}"/>
</target>

它被这样调用:

<phingcall target="--console-return-property">
    <property name="command" value="ps auxwww"/>
    <property name="checkreturn" value="true"/>
    <property name="logoutput" value="false"/>
    <property name="outputProperty" value="ps_output"/>
</phingcall>

它当然有效,因为它依赖于现有的exec,并且不是通用的...

答案 2 :(得分:0)

  

目标“子任务”应检查文件/文件夹的对应项是否在另一个目录“ 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>
        </if>
    </target>
</project>