view mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/Settings.java @ 93:a0aea01c32b0

improve repository url parsing
author Pavel.Sher
date Tue, 19 Jan 2010 22:23:15 +0300
parents e6971dc6b17c
children 6c1cff1f61cc
line wrap: on
line source
/*
 * Copyright 2000-2007 JetBrains s.r.o.
 *
 * 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.
 */
package jetbrains.buildServer.buildTriggers.vcs.mercurial.command;

import jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants;
import jetbrains.buildServer.buildTriggers.vcs.mercurial.PathUtil;
import jetbrains.buildServer.util.Hash;
import jetbrains.buildServer.util.StringUtil;
import jetbrains.buildServer.vcs.VcsRoot;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

/**
 * Represents Mercurial repository settings
 */
public class Settings {
  private String myRepository;
  private String myHgCommandPath;
  private File myWorkingDir;
  private File myWorkFolderParentDir;
  private String myUsername;
  private String myPassword;
  private String myBranchName;
  private static final String DEFAULT_BRANCH_NAME = "default";

  public Settings(@NotNull File workFolderParentDir, @NotNull VcsRoot vcsRoot) {
    myWorkFolderParentDir = workFolderParentDir;
    setRepository(vcsRoot.getProperty(Constants.REPOSITORY_PROP));
    setHgCommandPath(vcsRoot.getProperty(Constants.HG_COMMAND_PATH_PROP));
    myBranchName = vcsRoot.getProperty(Constants.BRANCH_NAME_PROP);

    myUsername = vcsRoot.getProperty(Constants.USERNAME);
    myPassword = vcsRoot.getProperty(Constants.PASSWORD);
  }

  public Settings() {
  }

  public void setRepository(@NotNull final String repository) {
    myRepository = repository;
  }

  /**
   * Returns name of the branch to use (returns 'default' if no branch specified)
   * @return see above
   */
  @NotNull
  public String getBranchName() {
    return StringUtil.isEmpty(myBranchName) ? DEFAULT_BRANCH_NAME : myBranchName;
  }

  /**
   * Returns true if current branch is default branch
   * @return see above
   */
  public boolean isDefaultBranch() {
    return getBranchName().equals(DEFAULT_BRANCH_NAME);
  }

  /**
   * Returns path to hg command
   * @return path to hg command
   */
  @NotNull
  public String getHgCommandPath() {
    return myHgCommandPath;
  }

  public String getUsername() {
    return myUsername;
  }

  public String getPassword() {
    return myPassword;
  }

  private final static Set<String> AUTH_PROTOS = new HashSet<String>();
  static {
    AUTH_PROTOS.add("http://");
    AUTH_PROTOS.add("https://");
    AUTH_PROTOS.add("ssh://");
  }

  /**
   * Returns URL to use for push command
   * @return URL to use for push command
   */
  public String getRepositoryUrl() {
    if (containsCredentials(myRepository)) return myRepository;

    for (String proto: AUTH_PROTOS) {
      if (myRepository.startsWith(proto)) {
        String repoUrl = myRepository.substring(proto.length());
        int endIdx = repoUrl.indexOf('@');
        int slashIdx = repoUrl.indexOf('/');
        if (endIdx != -1 && slashIdx > endIdx) {
          repoUrl = repoUrl.substring(endIdx+1);
        }

        String cre = "";
        if (!StringUtil.isEmpty(myUsername)) {
          cre += myUsername;
          if (!StringUtil.isEmpty(myPassword)) {
            cre += ":" + myPassword;
          }
          cre += "@";
        }

        return proto + cre + repoUrl;
      }
    }

    return myRepository;
  }

  private boolean containsCredentials(final String repository) {
    for (String proto: AUTH_PROTOS) {
      if (repository.startsWith(proto)) {
        String withoutProto = repository.substring(proto.length());
        int comma = withoutProto.indexOf(':');
        int at = withoutProto.indexOf('@');
        if (at != -1 && comma != -1 && at > comma) return true;
      }
    }
    return false;
  }

  public void setHgCommandPath(@NotNull final String hgCommandPath) {
    myHgCommandPath = hgCommandPath;
  }

  public void setWorkingDir(@NotNull final File workingDir) {
    myWorkingDir = PathUtil.getCanonicalFile(workingDir);
  }

  /**
   * Returns directory where repository is supposed to be cloned, i.e. working directory of cloned repository
   * @return repository working directory
   */
  @NotNull
  public File getLocalRepositoryDir() {
    if (myWorkingDir != null) {
      return myWorkingDir;
    }

    return getDefaultWorkDir(myWorkFolderParentDir, myRepository);
  }

  /**
   * Returns true if current working directory contains copy of repository (contains .hg directory)
   * @return see above
   */
  public boolean hasCopyOfRepository() {
    // need better way to check that repository copy is ok
    return getLocalRepositoryDir().isDirectory() && new File(getLocalRepositoryDir(), ".hg").isDirectory();
  }

  public static String DEFAULT_WORK_DIR_PREFIX = "hg_";

  private static File getDefaultWorkDir(@NotNull File workFolderParentDir, @NotNull String repPath) {
    String workingDirname = DEFAULT_WORK_DIR_PREFIX + String.valueOf(Hash.calc(normalize(repPath)));
    return PathUtil.getCanonicalFile(new File(workFolderParentDir, workingDirname));
  }

  private static String normalize(final String path) {
    String normalized = PathUtil.normalizeSeparator(path);
    if (path.endsWith("/")) {
      return normalized.substring(0, normalized.length()-1);
    }
    return normalized;
  }
}