how to get ivy:cachepath location without checking if dependencies downloaded

你。 提交于 2019-12-22 13:58:25

问题


I have a task in my build.xml:

<target name="init" depends="init-ivy">
  ...
  <ivy:cachepath
      inline="true"
      module="jersey-container-servlet"
      organisation="org.glassfish.jersey.containers"
      pathid="jersey.classpath"
      revision="2.23.2" />
  ...
</target>

This task downloads ivy if necessary (init-ivy does that actually) and then invokes ivy to download dependencies. It sets jersey.classpath as the result.

Right now my build task depends on the init task. So every time I build, it checks if dependencies need to be installed. I want to avoid checking dependencies every time and have build separate from init. But init sets jersey.classpath and build uses it.

Is there a way to obtain jersey.classpath from ivy without asking it to check dependencies? Is it even a good practice to not check dependencies in this case?


回答1:


As explained in this answer, ivy doesn't download jars every time it runs. It caches them locally under "~/.ivy2/cache":

  • Ant Download a Jar at Build

Secondly, you're using ivy in inline mode, presumably to avoid creating an ivy file? ivy cachepath is classified as post resolve task, which means it will automatically call the resolve task, in the background. What the inline mode does is tell ivy to perform a fresh resolve each time, which is wasteful if you have more than one classpath to manage.

Finally have you considered using an ivy file? A single call to the resolve task can work thru all your project's dependencies, cache this information locally and then determine if files need to be downloaded or not. I would recommend always resolving dependencies. It doesn't cost much and it's possible that things have changed between builds (for example if you're using dynamic dependencies, or Maven snapshots).

Here are my standard Ant targets for ivy look like:

  <available classname="org.apache.ivy.Main" property="ivy.installed"/>

  <target name="resolve" depends="install-ivy">
    <ivy:resolve/>

    <ivy:report todir='${ivy.reports.dir}' graph='false' xml='false'/>

    <ivy:cachepath pathid="compile.path" conf="compile"/>
    <ivy:cachepath pathid="runtime.path" conf="runtime"/>
    <ivy:cachepath pathid="test.path"    conf="test"/>
  </target>

  <target name="install-ivy" unless="ivy.installed">
    <mkdir dir="${user.home}/.ant/lib"/>
    <get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.4.0/ivy-2.4.0.jar"/>
    <fail message="Ivy has been installed. Run the build again"/>
  </target>

Notes:

  • Single target called "resolve" that calls ivy to manage my project classpaths. It also generates a useful report for documentation
  • The cachepath task is using ivy configurations to group or classify dependencies within the ivy file. This is really the efficiency magic that enables to save time on a single resolution.
  • Notice how the install-ivy task has a conditional check to determine if ivy is installed. This trick is not feasible with the rest of your project's dependencies due to complexity. My recommendation is ensure ivy exists and then use it to manage everything else. (Under the hood it'll do its best to be efficient). I don't really understand why Apache Ant doesn't bundle the ivy jar.


来源:https://stackoverflow.com/questions/39313778/how-to-get-ivycachepath-location-without-checking-if-dependencies-downloaded

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!