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
- application/pgp-signature attachment: stored
Received on Mon Feb 27 20:08:00 2006