<?xml version="1.0"?>
<!-- 
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 -->


<project
  xmlns:j="jelly:core"
  xmlns:i="jelly:interaction"
  xmlns:r="release:transform"
  xmlns:c="changes:transform"
  xmlns:log="jelly:log"
  xmlns:ant="jelly:ant"
  xmlns:doc="doc"
  xmlns:util="jelly:util"
  xmlns:maven="jelly:maven">

  <j:set var="scmMethod" value="${maven.scm.method}"/>

  <!--==================================================================-->
  <!-- Goal to validate SCM properties                                  -->
  <!--==================================================================-->
  <goal name="scm:parse-connection">
    <j:set var="checkValue" value="${maven.scm.ignore.pom.connection}"/>
    <j:if test="${!checkValue}">
      <j:set var="checkValue" value="${maven.scm.ignore.pom.developerConnection}"/>
      <j:if test="${!checkValue}">
        <j:set var="value" value="${pom.repository.developerConnection}"/>
        <j:if test="${!empty(value)}">
          <echo>Using connection: ${pom.repository.developerConnection}</echo>
          <j:set var="conn" value="${pom.repository.developerConnection}" />
        </j:if>
      </j:if>

      <j:if test="${conn == null}">
        <j:set var="value" value="${pom.repository.connection}"/>
        <j:if test="${!empty(value)}">
          <echo>Using connection: ${pom.repository.connection}</echo>
          <j:set var="conn" value="${pom.repository.connection}" />
        </j:if>
      </j:if>
    </j:if>

    <j:if test="${conn != null}">
      <j:set var="delim" value=":"/>
      <j:if test="${value.length() gt 3}">
        <j:set var="delim" value="${value.substring(3, 4)}"/>
      </j:if>
      <util:tokenize var="tokens" delim="${delim}">${conn}</util:tokenize>
      <j:if test="${tokens[0] != 'scm'}">
        <ant:fail>Invalid repository connection format</ant:fail>
      </j:if>
      <j:set var="maven.scm.method" value="${tokens[1]}"/>
      <j:set var="scmMethod" value="${maven.scm.method}"/>
      <log:info>Using SCM method: ${scmMethod}</log:info>
      <j:if test="${scmMethod == 'cvs'}">
        <j:choose>
          <j:when test="${tokens[2] == 'local'}">
            <j:set var="maven.scm.cvs.root" value=":${tokens[2]}:${tokens[3]}"/>
            <j:set var="maven.scm.cvs.module" value="${tokens[4]}"/>
          </j:when>
          <j:otherwise>
            <j:set var="maven.scm.cvs.root" value=":${tokens[2]}:${tokens[3]}:${tokens[4]}"/>
            <j:set var="maven.scm.cvs.module" value="${tokens[5]}"/>
          </j:otherwise>
        </j:choose>
        <log:info>Using CVSROOT: ${maven.scm.cvs.root}</log:info>
        <log:info>Using module: ${maven.scm.cvs.module}</log:info>
      </j:if>
    </j:if>
  </goal>

  <goal name="scm:validate" prereqs="scm:parse-connection">
    <j:choose>
      <j:when test="${scmMethod == 'cvs'}">
        <j:set var="cvsModule" value="${maven.scm.cvs.module}"/>
        <j:if test="${empty(cvsModule)}">
          <ant:fail>You must specify maven.scm.cvs.module</ant:fail>
        </j:if>
      </j:when>
      <j:otherwise>
        <ant:fail>Unknown SCM method: '${maven.scm.method}'</ant:fail>
      </j:otherwise>
    </j:choose>
  </goal>

  <!--==================================================================-->
  <!-- Goal to checkout a project                                       -->
  <!--==================================================================-->
  <goal name="scm:checkout-project"
    prereqs="scm:validate"
    description="Checkout a project">
    <j:if test="${scmMethod == 'cvs'}">
      <attainGoal name="scm:cvs-checkout-project"/>
    </j:if>
  </goal>

  <!--==================================================================-->
  <!-- Goal to bootstrap a project from SCM                             -->
  <!--==================================================================-->
  <goal name="scm:bootstrap-project"
    description="Bootstrap a project from SCM"
    prereqs="scm:checkout-project">
    <!-- TODO: check tagged syntax ok with other SCM than CVS, including in docs -->
    <j:set var="checkTagged" value="${maven.scm.check.tagged}"/>
    <j:if test="${checkTagged}">
      <!-- TODO: what about branch tags? Check <version>? What about cvs command for such? -->
      <j:set var="tag" value="${maven.scm.cvs.sticky.tag}"/>
      <j:if test="${tag == 'HEAD'}">
        <maven:pom var="project" projectDescriptor="${maven.scm.checkout.dir}/${maven.scm.cvs.module}/project.xml"/>
        <log:info>WARNING: you are releasing HEAD. This will overwrite any previous release versioned '${project.currentVersion}'.</log:info>
        <i:ask 
          question="Are you sure (y/n)?"
          answer="ok"
          default="n"
        />
        <j:if test="${ok != 'y'}">
          <ant:fail>Cancelled by response '${ok}'</ant:fail>
        </j:if> 
      </j:if>
    </j:if>

    <maven:maven
      descriptor="${maven.scm.bootstrap.pom.dir}/project.xml"
      goals="${maven.scm.bootstrap.goals}"
      ignoreFailures="false"
      />
  </goal>

  <!--==================================================================-->
  <!-- Goal to update a project                                         -->
  <!--==================================================================-->
  <goal name="scm:update-project"
    prereqs="scm:validate"
    description="Update a project from SCM">
    <j:if test="${scmMethod == 'cvs'}">
      <attainGoal name="scm:cvs-update-project"/>
    </j:if>
  </goal>

  <!--==================================================================-->
  <!-- Prepare Release                                                  -->
  <!--==================================================================-->
  <goal name="scm:prepare-release"
    prereqs="scm:validate"
    description="Prepare for a release in SCM">
    <j:if test="${scmMethod == 'cvs'}">
      <attainGoal name="scm:cvs-prepare-release"/>
    </j:if>
  </goal>
  
  <!--==================================================================-->
  <!-- Perform Release                                                  -->
  <!--   TODO: we should be able to select what to deploy and so on,    -->
  <!--         tie in with multiproject-by-groupId idea                 -->
  <!--==================================================================-->
  <goal name="scm:perform-release" prereqs="scm:parse-connection"
    description="Perform a release from SCM">
    <!-- Setup variables -->
    <j:choose>
      <j:when test="${scmMethod == 'cvs'}">
        <j:set var="module" value="${maven.scm.cvs.module}"/>
        <j:if test="${empty(module)}">
          <i:ask question="What CVS module are you releasing from?" answer="maven.scm.cvs.module"/>
        </j:if>
        <j:set var="tag" value="${maven.scm.cvs.sticky.tag}"/>
        <j:if test="${empty(tag)}">
          <i:ask question="What CVS tag are you releasing from?" answer="maven.scm.cvs.sticky.tag"/>
        </j:if>        
      </j:when>
      <j:when test="${empty(scmMethod)}">
        <ant:fail>You must specify maven.scm.method</ant:fail>
      </j:when> 
      <j:otherwise>
        <ant:fail>Unknown SCM method: ${scmMethod}</ant:fail>
      </j:otherwise>
    </j:choose>
    
    <j:set var="goals" value="${maven.scm.bootstrap.goals}"/>
    <j:if test="${empty(goals)}">
      <i:ask question="What goals are you using to build?" answer="maven.scm.bootstrap.goals" default="multiproject:deploy" />  
    </j:if>

    <attainGoal name="scm:bootstrap-project" />
  </goal>
  
  <!--==================================================================-->
  <!-- Checkout - CVS                                                   -->
  <!--==================================================================-->
  <goal name="scm:cvs-checkout-project">
    <j:set var="msg" value="Checking out ${maven.scm.cvs.module}" />
    <j:set var="value" value="${maven.scm.cvs.root}"/>
    <j:if test="${!empty(value)}">
      <j:set var="msg" value="${msg}; from CVSROOT: ${value}" />  
    </j:if> 
    <j:set var="value" value="${maven.scm.cvs.sticky.tag}"/>
    <j:if test="${!empty(value)}">
      <j:set var="msg" value="${msg}; using tag: ${value}" />  
    </j:if> 
    <ant:echo>${msg}</ant:echo>
    
    <j:set var="maven.scm.bootstrap.pom.dir" value="${maven.scm.checkout.dir}/${maven.scm.cvs.module}"/>
    <ant:delete dir="${maven.scm.bootstrap.pom.dir}"/>
    <ant:mkdir dir="${maven.scm.bootstrap.pom.dir}"/>
    <ant:cvs command="checkout ${maven.scm.cvs.checkout.flags}"
      quiet="${maven.scm.cvs.quiet}"
      cvsRsh="${maven.scm.cvs.rsh}"
      cvsRoot="${maven.scm.cvs.root}"
      dest="${maven.scm.checkout.dir}"
      package="${maven.scm.cvs.module}"
      tag="${maven.scm.cvs.sticky.tag}"
      failonerror="true"
      />
  </goal>

  <!--==================================================================-->
  <!-- Update - CVS                                                     -->
  <!--==================================================================-->
  <goal name="scm:cvs-update-project">
    <ant:cvs command="update ${maven.scm.cvs.update.flags}"
      quiet="${maven.scm.cvs.quiet}"
      cvsRsh="${maven.scm.cvs.rsh}"
      cvsRoot="${maven.scm.cvs.root}"
      tag="${maven.scm.cvs.sticky.tag}"
      failonerror="true"
      />
  </goal>
  
  <!--==================================================================-->
  <!-- Prepare Release - CVS                                            -->
  <!--==================================================================-->
  <goal name="scm:cvs-prepare-release">
    <log:info>Verifying no modifications are present</log:info>
    <j:set var="changesFilename" value="${maven.docs.src}/changes.xml" />
    <util:file var="file" name="${changesFilename}"/>
    <j:set var="changesExists" value="${file.exists()}" />
    <!-- Need to move POM out of the way as mods there are allowed -->
    <ant:move file="project.xml" tofile="project.xml.SCM.temp" />
    <j:set var="documents" value="project.xml" />
    <j:if test="${changesExists}">
      <maven:makeRelativePath basedir="${basedir}" path="${changesFilename}" var="changesFilename" />
      <util:replace var="changesFilename" value="${changesFilename}" oldChar="\\" newChar="/" />
      <j:set var="documents" value="${documents} ${changesFilename}" />
      <ant:move file="${changesFilename}" tofile="${changesFilename}.SCM.temp" />
    </j:if>
    <j:catch var="exception">
      <ant:cvs command="update ${documents}"
        quiet="${maven.scm.cvs.quiet}"
        cvsRsh="${maven.scm.cvs.rsh}"
        cvsRoot="${maven.scm.cvs.root}"
        failonerror="true"
      />
      <ant:cvs command="tag -c dummy_tag"
        noexec="true"
        quiet="${maven.scm.cvs.quiet}"
        cvsRsh="${maven.scm.cvs.rsh}"
        cvsRoot="${maven.scm.cvs.root}"
        failonerror="true"
      />
    </j:catch>
    <ant:move file="project.xml.SCM.temp" tofile="project.xml" />
    <j:if test="${changesExists}">
      <ant:move file="${changesFilename}.SCM.temp" tofile="${changesFilename}" />
    </j:if>
    <j:if test="${exception != null}">
      <ant:fail>${exception}</ant:fail>
    </j:if>
    <i:ask
      question="What is the new tag name?"
      answer="tag_name"
      default="${tag_name}"
    />
    <i:ask
      question="What is the new version?"
      answer="version_name"
      default="${tag_name}"
    />
    <log:info>Verifying valid tag name</log:info>
    <ant:cvs command="tag -F ${tag_name} project.xml"
      noexec="true"
      quiet="${maven.scm.cvs.quiet}"
      cvsRsh="${maven.scm.cvs.rsh}"
      cvsRoot="${maven.scm.cvs.root}"
      failonerror="true"
    />

    <r:release-version version="${version_name}" tag="${tag_name}" />
    <j:if test="${changesExists}">
      <c:release-version version="${version_name}" />
    </j:if>
    <log:info>Committing new documents: ${documents}</log:info>
    <ant:cvs command="commit -m '[maven-scm-plugin] prepare release ${version_name}' ${documents}"
      quiet="${maven.scm.cvs.quiet}"
      cvsRsh="${maven.scm.cvs.rsh}"
      cvsRoot="${maven.scm.cvs.root}"
      failonerror="true"
    />

    <log:info>Tagging source tree</log:info>
    <ant:cvs command="tag -F ${tag_name}"
      quiet="${maven.scm.cvs.quiet}"
      cvsRsh="${maven.scm.cvs.rsh}"
      cvsRoot="${maven.scm.cvs.root}"
      failonerror="true"
    />
  </goal>
</project>

