我希望有一个像这样的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
此目标,并希望访问由其设置的某些属性。
答案 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>