Daniel,
I never thought of allowing the use of multiple info targets in one
info tag. The reason I allowed for the specifying of the prefix was in case
you wanted to run info on multiple files/dirs but not overwrite the original
Ant properties set by the previous info calls. So you could do:
<!-- svn.info.* properties -->
<info file="${basedir}" />
that would use the defaults for setting the properties of the base and then
using:
<!-- svn.core.* properties -->
<info file="${basedir}/modules/core" rootPrefix="svn.core." />
and get properties that apply only for the core. I hope this makes sense.
That being said, I think the info support is documented well but maybe I
should add more use case examples like why you'd use the rootPrefix
attribute and how to run info against multiple files/dirs. Since this was
never really spec'd out, I just came up with my own approach and implemented
it. Obviously the community will drive this but as it is implemented, it
does address your questions just in different ways. What do you think?
Take care,
Jeremy
On 2/27/06, Daniel Rall <dlr@collab.net> wrote:
>
> Hello Jeremy, and thanks for your patience, and great start on the
> <info> command. I've committed a command based on your code in r2125.
> Please take a look at the commit, give it a whirl, and let me know
> whether everything still looks kosher.
>
> I modified a lot of the code, most notably adding support for running
> the <info> command against URIs, and refactoring the test suite. I
> didn't add any ra_dav or ra_svn tests for that functionality, but I
> think the test framework may provide a way to do this.
>
> Notably still missing is the ability to provide multiple targets to
> the <info> command. Were you thinking that the use of multiple <info>
> commands within a single <svn> task with different prefixes (e.g. for
> "foo.c", provide a "foo.c-" prefix or something)? I think this should
> be documented, or perhaps have much better support built right into
> the task. Any feedback (or more patches ;) ?
>
> - Dan
>
>
> On Tue, 14 Feb 2006, Jeremy Whitlock wrote:
>
> > Hey all,
> > There has been a lot of talk about this in recent months so I have
> gone
> > ahead and implemented "svn info" for the SvnAnt Ant tasks. This support
> is
> > fully unit tested and documented as if it were written by the
> maintainers of
> > SvnAnt. It takes advantage of svnClientAdapter so access to javahl and
> > command line adapters are available. There is one caveat where it does
> not
> > support the checksum feature since ISVNInfo doesn't expose a method to
> > obtaining it. I will research this and submit a patch at a later time.
> > Please review the attached patch and let me know if there is anything I
> can
> > do to fix an existing related issue.
> >
> > Take care,
> >
> > Jeremy
>
> > Index: C:/dev/java/svnant/test/svn/build.xml
> > ===================================================================
> > --- C:/dev/java/svnant/test/svn/build.xml (revision 2094)
> > +++ C:/dev/java/svnant/test/svn/build.xml (working copy)
> > @@ -1008,6 +1008,36 @@
> > <fileset refid="svnFileSetPatternSet"/>
> > </copy>
> > </target>
> > +
> > + <target name="testInfoNoAttributes" depends="init">
> > + <svn javahl="${javahl}" javasvn="${javasvn}">
> > + <info />
> > + </svn>
> > + </target>
> > +
> > + <target name="testInfoDirectory" depends="init">
> > + <svn javahl="${javahl}" javasvn="${javasvn}">
> > + <info file="${basedir}"/>
> > + </svn>
> > + </target>
> > +
> > + <target name="testInfoFile" depends="init">
> > + <svn javahl="${javahl}" javasvn="${javasvn}">
> > + <info file="${basedir}/build.xml"/>
> > + </svn>
> > + </target>
> > +
> > + <target name="testInfoBadFile" depends="init">
> > + <svn javahl="${javahl}" javasvn="${javasvn}">
> > + <info file="${basedir}/nullfile.txt"/>
> > + </svn>
> > + </target>
> > +
> > + <target name="testInfoCustomPrefix" depends="init">
> > + <svn javahl="${javahl}" javasvn="${javasvn}">
> > + <info file="${basedir}" propPrefix="wc.info" />
> > + </svn>
> > + </target>
> >
> > <target name="all" depends="init">
> > </target>
> > Index: C:/dev/java/svnant/doc/svn.html
> > ===================================================================
> > --- C:/dev/java/svnant/doc/svn.html (revision 2094)
> > +++ C:/dev/java/svnant/doc/svn.html (working copy)
> > @@ -123,36 +123,36 @@
> > <td>createRepository</td>
> > <td>import</td>
> > <td>move</td>
> > - <td>status</td>
> > + <td>revert</td>
> > </tr>
> > <tr>
> > <td>cat</td>
> > <td>delete</td>
> > + <td>info</td>
> > + <td>mkdir</td>
> > + <td>status</td>
> > + </tr>
> > + <tr>
> > + <td>checkout</td>
> > + <td>diff</td>
> > <td>keywordsset</td>
> > <td>propdel</td>
> > <td>switch</td>
> > </tr>
> > <tr>
> > - <td>checkout</td>
> > - <td>diff</td>
> > + <td>commit</td>
> > + <td>export</td>
> > <td>keywordsadd</td>
> > <td>propget</td>
> > <td>update</td>
> > </tr>
> > <tr>
> > - <td>commit</td>
> > - <td>export</td>
> > + <td>copy</td>
> > + <td>ignore</td>
> > <td>keywordsremove</td>
> > <td>propset</td>
> > <td></td>
> > </tr>
> > - <tr>
> > - <td>copy</td>
> > - <td>ignore</td>
> > - <td>mkdir</td>
> > - <td>revert</td>
> > - <td></td>
> > - </tr>
> > </table>
> > <p> </p>
> >
> > @@ -620,6 +620,33 @@
> > </tr>
> > </table>
> >
> > +<H3><a name="info">info</a></H3>
> > +<p>
> > +Gets the information from the repo for a file or directory and sets the
> values to Ant properties.<BR>
> > +</p>
> > +<table>
> > + <tr>
> > + <td>Attribute</td>
> > + <td>Description</td>
> > + <td>Required</td>
> > + </tr>
> > + <tr>
> > + <td>file</td>
> > + <td>Directory or file to gather the information
> about.</td>
> > + <td>Yes</td>
> > + </tr>
> > + <tr>
> > + <td>propPrefix</td>
> > + <td>Prefix to use for the Ant properties. Default is
> "svn.info.".</td>
> > + <td>False</td>
> > + </tr>
> > + <tr>
> > + <td>verbose</td>
> > + <td>Turns on verbosity for this Ant task. Default is
> "false".</td>
> > + <td>False</td>
> > + </tr>
> > +</table>
> > +
> > <H3><a name="keywordsset">keywordsset</a></H3>
> > <p>Keywordsset controls which keywords will be substituted on the
> > given files. Valid keywords are:
> > Index:
> C:/dev/java/svnant/src/main/org/tigris/subversion/svnant/SvnTask.java
> > ===================================================================
> > ---
> C:/dev/java/svnant/src/main/org/tigris/subversion/svnant/SvnTask.java
> (revision 2094)
> > +++
> C:/dev/java/svnant/src/main/org/tigris/subversion/svnant/SvnTask.java
> (working copy)
> > @@ -208,6 +208,10 @@
> > commands.add(a);
> > }
> >
> > + public void addInfo(Info a) {
> > + commands.add(a);
> > + }
> > +
> > public void addNotifyListener(ISVNNotifyListener notifyListener) {
> > notifyListeners.add(notifyListener);
> > }
> > Index:
> C:/dev/java/svnant/src/main/org/tigris/subversion/svnant/Info.java
> > ===================================================================
> > ---
> C:/dev/java/svnant/src/main/org/tigris/subversion/svnant/Info.java (revision
> 0)
> > +++
> C:/dev/java/svnant/src/main/org/tigris/subversion/svnant/Info.java (revision
> 0)
> > @@ -0,0 +1,181 @@
> > +package org.tigris.subversion.svnant;
> > +
> > +import java.io.File;
> > +
> > +import org.apache.tools.ant.BuildException;
> > +import org.apache.tools.ant.Project;
> > +import org.tigris.subversion.svnclientadapter.ISVNClientAdapter;
> > +import org.tigris.subversion.svnclientadapter.ISVNInfo;
> > +
> > +/**
> > + * svn info
> > + * @author Jeremy Whitlock
> > + * <a href="mailto:jwhitlock@collab.net">jwhitlock@collab.net</a>
> > + */
> > +public class Info extends SvnCommand {
> > +
> > + /** Path to the file to get properties from **/
> > + private String file = null;
> > +
> > + /** Whether or not to print the properties **/
> > + private boolean verbose = false;
> > +
> > + /** String prepended to new property names **/
> > + private String propPrefix = "svn.info.";
> > +
> > + /** Project reference **/
> > + private Project project = null;
> > +
> > + /** Subversion info **/
> > + private ISVNInfo info = null;
> > +
> > + /** Available directory properties **/
> > + private String[] dirProps = new String[] {
> > + "path",
> > + "url",
> > + "repouuid",
> > + "rev",
> > + "nodekind",
> > + "schedule",
> > + "author",
> > + "lastRev",
> > + "lastDate"
> > + };
> > +
> > + /** Available file properties **/
> > + private String[] fileProps = new String[] {
> > + "path",
> > + "name",
> > + "url",
> > + "repouuid",
> > + "rev",
> > + "nodekind",
> > + "schedule",
> > + "author",
> > + "lastRev",
> > + "lastDate",
> > + "lastTextUpdate",
> > + "lastPropUpdate",
> > + "checksum"
> > + };
> > +
> > + /**
> > + * @see org.tigris.subversion.svnant.SvnCommand#execute(
> org.tigris.subversion.svnclientadapter.ISVNClientAdapter)
> > + */
> > + public void execute(ISVNClientAdapter svnClient) throws
> BuildException {
> > + validateAttributes();
> > +
> > + if (verbose) {
> > + log("Svn: Info");
> > + }
> > +
> > + project = getProject();
> > +
> > + File wc = new File(file);
> > +
> > + if (wc.exists()) {
> > + try {
> > + info = svnClient.getInfo(wc);
> > + String[] props = null;
> > +
> > + if (wc.isDirectory()) {
> > + props = dirProps;
> > + } else {
> > + props = fileProps;
> > + }
> > +
> > + for (int i = 0; i < props.length; i++) {
> > + String value = getValue(props[i]);
> > +
> > + project.setProperty(propPrefix +
> props[i], value);
> > +
> > + if (verbose) {
> > + log(" " + propPrefix +
> props[i] + ": " + value, Project.MSG_INFO);
> > + }
> > + }
> > + } catch (Exception e) {
> > + throw new BuildException(e);
> > + }
> > + } else {
> > + throw new BuildException("Dir must be set to an
> existing file/directory in your working copy.");
> > + }
> > + }
> > +
> > + /**
> > + * Gets the proper info property
> > + * @param prop String representation of the property
> > + * @return String value of the property
> > + */
> > + public String getValue(String prop) {
> > + String value = null;
> > +
> > + if (prop.equals(fileProps[0])) {
> > + value = info.getFile().getAbsolutePath();
> > + } else if (prop.equals(fileProps[1])) {
> > + value = info.getFile().getName();
> > + } else if (prop.equals(fileProps[2])) {
> > + value = info.getUrl().toString();
> > + } else if (prop.equals(fileProps[3])) {
> > + value = info.getUuid();
> > + } else if (prop.equals(fileProps[4])) {
> > + value = info.getRevision().toString();
> > + } else if (prop.equals(fileProps[5])) {
> > + value = info.getNodeKind().toString();
> > + } else if (prop.equals(fileProps[6])) {
> > + value = info.getSchedule().toString();
> > + } else if (prop.equals(fileProps[7])) {
> > + value = info.getLastCommitAuthor();
> > + } else if (prop.equals(fileProps[8])) {
> > + value = info.getLastChangedRevision().toString();
> > + } else if (prop.equals(fileProps[9])) {
> > + value = info.getLastChangedDate().toString();
> > + } else if (prop.equals(fileProps[10])) {
> > + value = info.getLastDateTextUpdate().toString();
> > + } else if (prop.equals(fileProps[11])) {
> > + value = info.getLastDatePropsUpdate().toString();
> > + } else if (prop.equals(fileProps[12])) {
> > + value = "Checksum is not implemented!";
> > + } else {
> > + value = prop + " is an invalid property!";
> > + }
> > +
> > + return value;
> > + }
> > +
> > + /**
> > + * Validates the call to svn info
> > + */
> > + public void validateAttributes() {
> > + if (file == null) {
> > + throw new BuildException("File must be set to a
> file/directory of your local working copy.");
> > + }
> > + }
> > +
> > + /**
> > + * Set the path to the file/dir
> > + * @param file
> > + */
> > + public void setFile(String file) {
> > + this.file = Project.translatePath(file);
> > + }
> > +
> > + /**
> > + * Sets whether or not we output the properties we set
> > + * @param verbose
> > + */
> > + public void setVerbose(boolean verbose) {
> > + this.verbose = verbose;
> > + }
> > +
> > + /**
> > + * Sets the Ant property prefix
> > + * @param propPrefix
> > + */
> > + public void setPropPrefix(String propPrefix) {
> > + if (propPrefix.endsWith(".")) {
> > + this.propPrefix = propPrefix;
> > + } else {
> > + this.propPrefix = propPrefix + ".";
> > + }
> > + }
> > +}
> > Index:
> C:/dev/java/svnant/src/testcases/org/tigris/subversion/svnant/SvnTest.java
> > ===================================================================
> > ---
> C:/dev/java/svnant/src/testcases/org/tigris/subversion/svnant/SvnTest.java (revision
> 2094)
> > +++
> C:/dev/java/svnant/src/testcases/org/tigris/subversion/svnant/SvnTest.java (working
> copy)
> > @@ -815,8 +815,53 @@
> > assertEquals(1, dir.listFiles().length);
> > assertTrue( (new File(dir, "file3.xml")).exists() );
> > }
> > -
> >
> > + public void testSvnInfo() throws Exception {
> > + // Here only for debugging the test
> > + try {
> > + expectBuildException("testInfoNoAttributes", "Dir
> or file must be set.");
> > + expectBuildException("testInfoBadFile", "
> fakefile.txt: (Not a versioned resource)");
> > +
> > + executeTarget("testInfoFile");
> > +
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.path"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.name"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.url"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.repouuid"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.rev"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.nodekind"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.schedule"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.author"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.lastRev"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.lastDate"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.lastTextUpdate"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.lastPropUpdate"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.checksum"));
> > +
> > + executeTarget("testInfoDir");
> > +
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.path"));
> > + assertNull("Property should be null!",
> project.getProperty("svn.info.name"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.url"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.repouuid"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.rev"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.nodekind"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.schedule"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.author"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.lastRev"));
> > + assertNotNull("Property should be set!",
> project.getProperty("svn.info.lastDate"));
> > + assertNull("Property should be null!",
> project.getProperty("svn.info.lastTextUpdate"));
> > + assertNull("Property should be null!",
> project.getProperty("svn.info.lastPropUpdate"));
> > + assertNull("Property should be null!",
> project.getProperty("svn.info.checksum"));
> > +
> > + executeTarget("testInfoCustomPrefix");
> > +
> > + assertNotNull("Property should not be null!",
> project.getProperty("wc.info.path"));
> > + } catch (Exception e) {
> > + e.printStackTrace();
> > + }
> > + }
> > +
> > /**
> > * This is not actually a test case, but a hook to assure that
> > * cleanup is handled after all test cases have run (rather than
>
>
> --
>
> Daniel Rall
>
>
>
Received on Mon Feb 27 20:18:06 2006