<commit_before>/*
 * The MIT License
 * 
 * Copyright (c) 2004-2009, Sun Microsystems, Inc., <NAME>, <NAME>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package hudson.scm;

import hudson.ExtensionPoint;
import hudson.FilePath;
import hudson.Launcher;
import hudson.DescriptorExtensionList;
import hudson.Extension;
import hudson.security.PermissionGroup;
import hudson.security.Permission;
import hudson.tasks.Builder;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Describable;
import hudson.model.TaskListener;
import hudson.model.Node;
import hudson.model.WorkspaceCleanupThread;
import hudson.model.Hudson;
import hudson.model.Descriptor;
import hudson.model.Api;
import hudson.model.Action;
import hudson.model.AbstractProject.AbstractProjectDescriptor;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;

import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

/**
 * Captures the configuration information in it.
 *
 * <p>
 * To register a custom {@link SCM} implementation from a plugin,
 * put {@link Extension} on your {@link SCMDescriptor}.
 *
 * <p>
 * Use the "project-changes" view to render change list to be displayed
 * at the project level. The default implementation simply aggregates
 * change lists from builds, but your SCM can provide different views.
 * The view gets the "builds" variable which is a list of builds that are
 * selected for the display.
 *
 * <p>
 * If you are interested in writing a subclass in a plugin,
 * also take a look at <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Writing+an+SCM+plugin">
 * "Writing an SCM plugin"</a> wiki article.
 *
 * @author <NAME>
 */
@ExportedBean
public abstract class SCM implements Describable<SCM>, ExtensionPoint {
    /**
     * Stores {@link AutoBrowserHolder}. Lazily created.
     */
    private transient AutoBrowserHolder autoBrowserHolder;

    /**
     * Expose {@link SCM} to the remote API.
     */
    public Api getApi() {
        return new Api(this);
    }

    /**
     * Returns the {@link RepositoryBrowser} for files
     * controlled by this {@link SCM}.
     *
     * @return
     *      null to indicate that there's no explicitly configured browser
     *      for this SCM instance.
     *
     * @see #getEffectiveBrowser()
     */
    public RepositoryBrowser<?> getBrowser() {
        return null;
    }

    /**
     * Type of this SCM.
     *
     * Exposed so that the client of the remote API can tell what SCM this is.
     */
    @Exported
    public String getType() {
        return getClass().getName();
    }

    /**
     * Returns the applicable {@link RepositoryBrowser} for files
     * controlled by this {@link SCM}.
     *
     * <p>
     * This method attempts to find applicable browser
     * from other job configurations.
     */
    @Exported(name="browser")
    public final RepositoryBrowser<?> getEffectiveBrowser() {
        RepositoryBrowser<?> b = getBrowser();
        if(b!=null)
            return b;
        if(autoBrowserHolder==null)
            autoBrowserHolder = new AutoBrowserHolder(this);
        return autoBrowserHolder.get();

    }

    /**
     * Returns true if this SCM supports
     * {@link #poll(AbstractProject, Launcher, FilePath, TaskListener, SCMRevisionState) poling}.
     *
     * @since 1.105
     */
    public boolean supportsPolling() {
        return true;
    }
    
    /**
     * Returns true if this SCM requires a checked out workspace for doing polling.
     *
     * <p>
     * This flag affects the behavior of Hudson when a job lost its workspace
     * (typically due to a slave outage.) If this method returns false and
     * polling is configured, then that would immediately trigger a new build.
     *
     * <p>
     * This flag also affects the mutual exclusion control between builds and polling.
     * If this methods returns false, polling will continu asynchronously even
     * when a build is in progress, but otherwise the polling activity is blocked
     * if a build is currently using a workspace.
     *
     * <p>
     * The default implementation returns true.
     *
     * <p>
     * See issue #1348 for more discussion of this feature.
     *
     * @since 1.196
     */
    public boolean requiresWorkspaceForPolling() {
    	return true;
    }

    /**
     * Called before a workspace is deleted on the given node, to provide SCM an opportunity to perform clean up.
     *
     * <p>
     * Hudson periodically scans through all the slaves and removes old workspaces that are deemed unnecesasry.
     * This behavior is implemented in {@link WorkspaceCleanupThread}, and it is necessary to control the
     * disk consumption on slaves. If we don't do this, in a long run, all the slaves will have workspaces
     * for all the projects, which will be prohibitive in big Hudson.
     *
     * <p>
     * However, some SCM implementations require that the server be made aware of deletion of the local workspace,
     * and this method provides an opportunity for SCMs to perform such a clean-up act.
     *
     * <p>
     * This call back is invoked after Hudson determines that a workspace is unnecessary, but before the actual
     * recursive directory deletion happens.
     *
     * <p>
     * Note that this method does not guarantee that such a clean up will happen. For example, slaves can be
     * taken offline by being physically removed from the network, and in such a case there's no opporunity
     * to perform this clean up. Similarly, when a project is deleted or renamed, SCMs do not get any notifications.
     *
     * @param project
     *      The project that owns this {@link SCM}. This is always the same object for a particular instance
     *      of {@link SCM}. Just passed in here so that {@link SCM} itself doesn't have to remember the value.
     * @param workspace
     *      The workspace which is about to be deleted. Never null. This can be a remote file path.
     * @param node
     *      The node that hosts the workspace. SCM can use this information to determine the course of action.
     *
     * @return
     *      true if {@link SCM} is OK to let Hudson proceed with deleting the workspace.
     *      False to veto the workspace deletion.<commit_msg>this callback does happen when the project is deleted.<commit_after>/*
 * The MIT License
 * 
 * Copyright (c) 2004-2009, Sun Microsystems, Inc., <NAME>, <NAME>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package hudson.scm;

import hudson.ExtensionPoint;
import hudson.FilePath;
import hudson.Launcher;
import hudson.DescriptorExtensionList;
import hudson.Extension;
import hudson.security.PermissionGroup;
import hudson.security.Permission;
import hudson.tasks.Builder;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Describable;
import hudson.model.TaskListener;
import hudson.model.Node;
import hudson.model.WorkspaceCleanupThread;
import hudson.model.Hudson;
import hudson.model.Descriptor;
import hudson.model.Api;
import hudson.model.Action;
import hudson.model.AbstractProject.AbstractProjectDescriptor;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;

import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

/**
 * Captures the configuration information in it.
 *
 * <p>
 * To register a custom {@link SCM} implementation from a plugin,
 * put {@link Extension} on your {@link SCMDescriptor}.
 *
 * <p>
 * Use the "project-changes" view to render change list to be displayed
 * at the project level. The default implementation simply aggregates
 * change lists from builds, but your SCM can provide different views.
 * The view gets the "builds" variable which is a list of builds that are
 * selected for the display.
 *
 * <p>
 * If you are interested in writing a subclass in a plugin,
 * also take a look at <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Writing+an+SCM+plugin">
 * "Writing an SCM plugin"</a> wiki article.
 *
 * @author <NAME>
 */
@ExportedBean
public abstract class SCM implements Describable<SCM>, ExtensionPoint {
    /**
     * Stores {@link AutoBrowserHolder}. Lazily created.
     */
    private transient AutoBrowserHolder autoBrowserHolder;

    /**
     * Expose {@link SCM} to the remote API.
     */
    public Api getApi() {
        return new Api(this);
    }

    /**
     * Returns the {@link RepositoryBrowser} for files
     * controlled by this {@link SCM}.
     *
     * @return
     *      null to indicate that there's no explicitly configured browser
     *      for this SCM instance.
     *
     * @see #getEffectiveBrowser()
     */
    public RepositoryBrowser<?> getBrowser() {
        return null;
    }

    /**
     * Type of this SCM.
     *
     * Exposed so that the client of the remote API can tell what SCM this is.
     */
    @Exported
    public String getType() {
        return getClass().getName();
    }

    /**
     * Returns the applicable {@link RepositoryBrowser} for files
     * controlled by this {@link SCM}.
     *
     * <p>
     * This method attempts to find applicable browser
     * from other job configurations.
     */
    @Exported(name="browser")
    public final RepositoryBrowser<?> getEffectiveBrowser() {
        RepositoryBrowser<?> b = getBrowser();
        if(b!=null)
            return b;
        if(autoBrowserHolder==null)
            autoBrowserHolder = new AutoBrowserHolder(this);
        return autoBrowserHolder.get();

    }

    /**
     * Returns true if this SCM supports
     * {@link #poll(AbstractProject, Launcher, FilePath, TaskListener, SCMRevisionState) poling}.
     *
     * @since 1.105
     */
    public boolean supportsPolling() {
        return true;
    }
    
    /**
     * Returns true if this SCM requires a checked out workspace for doing polling.
     *
     * <p>
     * This flag affects the behavior of Hudson when a job lost its workspace
     * (typically due to a slave outage.) If this method returns false and
     * polling is configured, then that would immediately trigger a new build.
     *
     * <p>
     * This flag also affects the mutual exclusion control between builds and polling.
     * If this methods returns false, polling will continu asynchronously even
     * when a build is in progress, but otherwise the polling activity is blocked
     * if a build is currently using a workspace.
     *
     * <p>
     * The default implementation returns true.
     *
     * <p>
     * See issue #1348 for more discussion of this feature.
     *
     * @since 1.196
     */
    public boolean requiresWorkspaceForPolling() {
    	return true;
    }

    /**
     * Called before a workspace is deleted on the given node, to provide SCM an opportunity to perform clean up.
     *
     * <p>
     * Hudson periodically scans through all the slaves and removes old workspaces that are deemed unnecesasry.
     * This behavior is implemented in {@link WorkspaceCleanupThread}, and it is necessary to control the
     * disk consumption on slaves. If we don't do this, in a long run, all the slaves will have workspaces
     * for all the projects, which will be prohibitive in big Hudson.
     *
     * <p>
     * However, some SCM implementations require that the server be made aware of deletion of the local workspace,
     * and this method provides an opportunity for SCMs to perform such a clean-up act.
     *
     * <p>
     * This call back is invoked after Hudson determines that a workspace is unnecessary, but before the actual
     * recursive directory deletion happens.
     *
     * <p>
     * Note that this method does not guarantee that such a clean up will happen. For example, slaves can be
     * taken offline by being physically removed from the network, and in such a case there's no opportunity
     * to perform this clean up.
     *
     * <p>
     * This method is also invoked when the project is deleted.
     *
     * @param project
     *      The project that owns this {@link SCM}. This is always the same object for a particular instance
     *      of {@link SCM}. Just passed in here so that {@link SCM} itself doesn't have to remember the value.
     * @param workspace
     *      The workspace which is about to be deleted. Never null. This can be a remote file path.
     * @param node
     *      The node that hosts the workspace. SCM can use this information to determine the course of action.
     *
     * @return
     *      true if {@link SCM} is OK to let Hudson proceed with deleting the workspace.
     *      False to veto the workspace deletion.
{'fraction_non_alphanumeric': 0.07528029898558462, 'fraction_numerical': 0.0026695141484249867, 'mean_word_length': 2.9885546978972584, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '960123', 'n_tokens_mistral': 4096, 'n_tokens_neox': 3895, 'n_words': 1770}