Skip to content

Commit

Permalink
enabled saving to branch
Browse files Browse the repository at this point in the history
  • Loading branch information
grzegorz7 committed Nov 7, 2014
1 parent f2f9578 commit 90f1e93
Show file tree
Hide file tree
Showing 16 changed files with 147 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import hudson.plugins.scm_sync_configuration.model.ScmContext;
import hudson.plugins.scm_sync_configuration.scms.SCM;
import org.apache.maven.scm.ScmException;
import org.apache.maven.scm.ScmFile;
import org.apache.maven.scm.ScmFileSet;
import org.apache.maven.scm.*;
import org.apache.maven.scm.command.add.AddScmResult;
import org.apache.maven.scm.command.checkin.CheckInScmResult;
import org.apache.maven.scm.command.checkout.CheckOutScmResult;
Expand Down Expand Up @@ -35,6 +33,7 @@ public class SCMManipulator {
private ScmManager scmManager;
private ScmRepository scmRepository = null;
private String scmSpecificFilename = null;
private String scmGitBranch;

public SCMManipulator(ScmManager _scmManager) {
this.scmManager = _scmManager;
Expand Down Expand Up @@ -65,7 +64,8 @@ public boolean scmConfigurationSettledUp(ScmContext scmContext, boolean resetScm
return false;
}
}


scmGitBranch = scmContext.getScmGitBranch();
return expectScmRepositoryInitiated();
}

Expand All @@ -88,7 +88,12 @@ public boolean checkout(File checkoutDirectory){
// Checkouting sources
LOGGER.fine("Checkouting SCM files into ["+checkoutDirectory.getAbsolutePath()+"] ...");
try {
CheckOutScmResult result = scmManager.checkOut(this.scmRepository, new ScmFileSet(checkoutDirectory));
ScmBranch scmBranch = null;
if (scmGitBranch != null && scmGitBranch.length() > 0){
scmBranch = new ScmBranch(scmGitBranch);
}
CheckOutScmResult result = scmManager.checkOut(this.scmRepository, new ScmFileSet(checkoutDirectory),scmBranch);

if(!result.isSuccess()){
LOGGER.severe("[checkout] Error during checkout : "+result.getProviderMessage()+" || "+result.getCommandOutput());
return checkoutOk;
Expand Down Expand Up @@ -262,5 +267,4 @@ public boolean checkinFiles(File scmRoot, String commitMessage){
public String getScmSpecificFilename() {
return scmSpecificFilename;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void init(ScmContext scmContext) throws ComponentLookupException, PlexusC
this.scmManipulator = new SCMManipulator(scmManager);
this.checkoutScmDirectory = new File(getCheckoutScmDirectoryAbsolutePath());
this.checkoutSucceeded = false;
initializeRepository(scmContext, false);
initializeRepository(scmContext, true);
}

public void initializeRepository(ScmContext scmContext, boolean deleteCheckoutScmDir){
Expand Down Expand Up @@ -304,10 +304,34 @@ public boolean scmCheckoutDirectorySettledUp(ScmContext scmContext){
}

public List<File> reloadAllFilesFromScm() throws IOException, ScmException {
//removeSourceJobsDuringReload();
this.scmManipulator.update(new File(getCheckoutScmDirectoryAbsolutePath()));
return syncDirectories(new File(getCheckoutScmDirectoryAbsolutePath() + File.separator), "");
}

/**
*
* @param from configuration checked out from SCM
* @param relative
* @return
* @throws IOException
*/
public List<File> removeSourceJobsDuringReload() throws IOException {
List<File> l = new ArrayList<File>();
File jobsFolder = new File(Hudson.getInstance().getRootDir().toString()+ "/jobs");
LOGGER.info("Configuration reload - jobs removal. Cleaning up folder:"+jobsFolder);

for(File f : jobsFolder.listFiles()){
l.add(f);
if (f.isDirectory()) {
FileUtils.deleteDirectory(f);
} else {
FileUtils.forceDelete(f);
}
}
return l;
}

private List<File> syncDirectories(File from, String relative) throws IOException {
List<File> l = new ArrayList<File>();
for(File f : from.listFiles()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public static interface AtomicTransactionFactory {
private transient Future<Void> latestCommitFuture;

private String scmRepositoryUrl;
private String scmGitBranch;
private SCM scm;
private boolean noUserCommitMessage;
private boolean displayStatus = true;
Expand All @@ -96,6 +97,9 @@ public static interface AtomicTransactionFactory {
private String commitMessagePattern = "[message]";
private List<File> filesModifiedByLastReload;
private List<String> manualSynchronizationIncludes;
private String scmBranchToReload;

private static final String SCM_SYNC_GIT_PREFX="scm:git:";

public ScmSyncConfigurationPlugin(){
// By default, transactions should be asynchronous
Expand Down Expand Up @@ -140,6 +144,7 @@ public void start() throws Exception {

public void loadData(ScmSyncConfigurationPOJO pojo){
this.scmRepositoryUrl = pojo.getScmRepositoryUrl();
this.scmGitBranch = pojo.getScmGitBranch();
this.scm = pojo.getScm();
this.noUserCommitMessage = pojo.isNoUserCommitMessage();
this.displayStatus = pojo.isDisplayStatus();
Expand Down Expand Up @@ -174,16 +179,26 @@ public void configure(StaplerRequest req, JSONObject formData)
this.displayStatus = formData.getBoolean("displayStatus");
this.commitMessagePattern = req.getParameter("commitMessagePattern");

String oldGitBranch = this.scmGitBranch;
String oldScmRepositoryUrl = this.scmRepositoryUrl;
String scmType = req.getParameter("scm");
if(scmType != null){
this.scm = SCM.valueOf(scmType);
String newScmRepositoryUrl = this.scm.createScmUrlFromRequest(req);

this.scmRepositoryUrl = newScmRepositoryUrl;
String newScmGitBranch = formData.getJSONObject("scm").getString("scmGitBranch");

if (oldGitBranch == null) {
oldGitBranch = "master";
}
if (newScmGitBranch == null){
newScmGitBranch = "master";
}
this.scmGitBranch = newScmGitBranch;

// If something changed, let's reinitialize repository in working directory !
repoInitializationRequired = newScmRepositoryUrl != null && !newScmRepositoryUrl.equals(oldScmRepositoryUrl);
repoInitializationRequired = (newScmRepositoryUrl != null && !newScmRepositoryUrl.equals(oldScmRepositoryUrl)) || !newScmGitBranch.equals(oldGitBranch);
configsResynchronizationRequired = repoInitializationRequired;
repoCleaningRequired = newScmRepositoryUrl==null && oldScmRepositoryUrl!=null;
}
Expand Down Expand Up @@ -222,7 +237,14 @@ public void configure(StaplerRequest req, JSONObject formData)

public void doReloadAllFilesFromScm(StaplerRequest req, StaplerResponse res) throws ServletException, IOException {
try {
filesModifiedByLastReload = business.reloadAllFilesFromScm();
String branchToReload = req.getParameter("scmBranchReload");
String urlToReload = req.getParameter("urlRepoReload");
LOGGER.info("Switching to URL:" + urlToReload + " branch:"+ branchToReload);
scmGitBranch = branchToReload;
scmRepositoryUrl = SCM_SYNC_GIT_PREFX + urlToReload;
business.removeSourceJobsDuringReload();
init();
filesModifiedByLastReload = business.reloadAllFilesFromScm();
req.getView(this, "/hudson/plugins/scm_sync_configuration/reload.jelly").forward(req, res);
}
catch(ScmException e) {
Expand Down Expand Up @@ -285,7 +307,7 @@ public ScmSyncStrategy getStrategyForSaveable(Saveable s, File f){
}

public ScmContext createScmContext(){
return new ScmContext(this.scm, this.scmRepositoryUrl, this.commitMessagePattern);
return new ScmContext(this.scm, this.scmRepositoryUrl, this.commitMessagePattern, this.scmGitBranch);
}

public boolean shouldDecorationOccursOnURL(String url){
Expand Down Expand Up @@ -347,7 +369,9 @@ public String getScmUrl(){
}
}

public List<File> getFilesModifiedByLastReload() {
public String getScmGitBranch() { return scmGitBranch; }

public List<File> getFilesModifiedByLastReload() {
return filesModifiedByLastReload;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@ public class ScmContext {
private String scmRepositoryUrl;
private SCM scm;
private String commitMessagePattern;
private String scmGitBranch;

public ScmContext(SCM _scm, String _scmRepositoryUrl){
this(_scm, _scmRepositoryUrl, "[message]");
}

public ScmContext(SCM _scm, String _scmRepositoryUrl, String _commitMessagePattern){
this.scm = _scm;
this.scmRepositoryUrl = _scmRepositoryUrl;
this.commitMessagePattern = _commitMessagePattern;
this(_scm, _scmRepositoryUrl, _commitMessagePattern, null);
}

public ScmContext(SCM _scm, String _scmRepositoryUrl, String _commitMessagePattern, String _scmGitBranch){
this.scm = _scm;
this.scmRepositoryUrl = _scmRepositoryUrl;
this.commitMessagePattern = _commitMessagePattern;
this.scmGitBranch = _scmGitBranch;
}

public String getScmRepositoryUrl() {
return scmRepositoryUrl;
}
Expand All @@ -28,6 +34,10 @@ public SCM getScm() {
return scm;
}

public String getScmGitBranch() {
return scmGitBranch;
}

public String getCommitMessagePattern(){
return commitMessagePattern;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public String getRepositoryUrlHelpPath() {
public ScmRepository getConfiguredRepository(ScmManager scmManager, String scmRepositoryURL) {
SCMCredentialConfiguration credentials = extractScmCredentials( extractScmUrlFrom(scmRepositoryURL) );

LOGGER.info("Creating SCM repository object for url : "+scmRepositoryURL);
LOGGER.info("" +
"Creating SCM repository object for url : "+scmRepositoryURL);
ScmRepository repository = null;
try {
repository = scmManager.makeScmRepository( scmRepositoryURL );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* checkin is originally made by passing pushUrl instead of a local reference (such as "origin")
* Problem is passing pushUrl doesn't update current local reference once pushed => after push,
* origin/<targetBranch> will not be updated to latest commit => on next push, there will be an
* error saying some pull is needed.
* error saying some ull is needed.
* This workaround could be betterly handled when something like "checkinAndFetch" could be
* implemented generically in maven-scm-api
* (see http://maven.40175.n5.nabble.com/SCM-GitExe-no-fetch-after-push-td5745064.html)
Expand Down Expand Up @@ -113,7 +113,11 @@ protected CheckInScmResult executeCheckInCommand(
if( repo.isPushChanges() )
{
Commandline cl = createSpecificPushCommandLine( getLogger(), repository, fileSet, version );

StringBuffer clOutput = new StringBuffer();
String[] clTab = cl.getCommandline();
for (int i = 0; i < clTab.length; i++) {
clOutput.append(clTab[i] + ", ");
}
exitCode = GitCommandLineUtils.execute( cl, stdout, stderr, getLogger() );
if ( exitCode != 0 )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ public void marshal(Object source, HierarchicalStreamWriter writer,
writer.setValue(plugin.getScmRepositoryUrl());
writer.endNode();
}
if(plugin.getScmGitBranch() != null){
writer.startNode(AbstractMigrator.SCM_GIT_BRANCH);
writer.setValue(plugin.getScmGitBranch());
writer.endNode();
}

writer.startNode(AbstractMigrator.SCM_NO_USER_COMMIT_MESSAGE);
writer.setValue(Boolean.toString(plugin.isNoUserCommitMessage()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public abstract class AbstractMigrator<TFROM extends ScmSyncConfigurationPOJO, T
public static final String SCM_DISPLAY_STATUS = "displayStatus";
public static final String SCM_COMMIT_MESSAGE_PATTERN = "commitMessagePattern";
public static final String SCM_MANUAL_INCLUDES = "manualSynchronizationIncludes";
public static final String SCM_GIT_BRANCH = "scmGitBranch";

private static final Logger LOGGER = Logger.getLogger(AbstractMigrator.class.getName());

Expand All @@ -36,6 +37,7 @@ public TTO readScmSyncConfigurationPOJO(
TTO pojo = createMigratedPojo();

String scmRepositoryUrl = null;
String scmGitBranch = null;
String scmClassAttribute = null;
String scmContent = null;
boolean noUserCommitMessage = false;
Expand All @@ -45,8 +47,10 @@ public TTO readScmSyncConfigurationPOJO(

while(reader.hasMoreChildren()){
reader.moveDown();
if(SCM_REPOSITORY_URL_TAG.equals(reader.getNodeName())){
scmRepositoryUrl = reader.getValue();
if(SCM_REPOSITORY_URL_TAG.equals(reader.getNodeName())) {
scmRepositoryUrl = reader.getValue();
} else if (SCM_GIT_BRANCH.equals(reader.getNodeName())){
scmGitBranch = reader.getValue();
} else if(SCM_NO_USER_COMMIT_MESSAGE.equals(reader.getNodeName())){
noUserCommitMessage = Boolean.parseBoolean(reader.getValue());
} else if(SCM_DISPLAY_STATUS.equals(reader.getNodeName())){
Expand Down Expand Up @@ -74,6 +78,7 @@ public TTO readScmSyncConfigurationPOJO(

pojo.setScm(createSCMFrom(scmClassAttribute, scmContent));
pojo.setScmRepositoryUrl(scmRepositoryUrl);
pojo.setScmGitBranch(scmGitBranch);
pojo.setNoUserCommitMessage(noUserCommitMessage);
pojo.setDisplayStatus(displayStatus);
pojo.setCommitMessagePattern(commitMessagePattern);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
public class DefaultSSCPOJO implements ScmSyncConfigurationPOJO {

private String scmRepositoryUrl;
private String scmGitBranch;
private SCM scm;
private boolean noUserCommitMessage;
private boolean displayStatus;
Expand All @@ -19,7 +20,13 @@ public String getScmRepositoryUrl() {
public void setScmRepositoryUrl(String scmRepositoryUrl) {
this.scmRepositoryUrl = scmRepositoryUrl;
}
public SCM getScm() {
public String getScmGitBranch() {
return scmGitBranch;
}
public void setScmGitBranch(String scmGitBranch) {
this.scmGitBranch = scmGitBranch;
}
public SCM getScm() {
return scm;
}
public void setScm(SCM scm) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
public interface ScmSyncConfigurationPOJO {
public String getScmRepositoryUrl();
public void setScmRepositoryUrl(String scmRepositoryUrl);
public String getScmGitBranch();
public void setScmGitBranch(String scmGitBranch);
public SCM getScm();
public void setScm(SCM scm);
public boolean isNoUserCommitMessage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,26 @@
</table>
</f:repeatable>
</f:entry>
<f:entry title="${%Reload config from SCM}" help="${rootUrl}/plugin/scm-sync-configuration/help/reloadScmConfig-help.html">
<a href="${rootURL}/plugin/scm-sync-configuration/reloadAllFilesFromScm" onClick="return confirm('${%WARNING : the Jenkins config will be reloaded from SCM}.\n${%Only file modifications are handled}. ${%File added or removed will not be handled} !\n\n${%Continue} ?')">${%Reload}</a>

<f:entry title="${%Branch reloading}">
<table width="100%">
<f:entry title="${%URL Repository to reload from SCM}" help="${rootUrl}/plugin/scm-sync-configuration/help/reloadScmConfig-url-help.html">
<f:textbox id="urlRepoReloadTextId" name="scmURLReload" value="${it.scmURLReload}" />
</f:entry>

<f:entry title="${%Branch to reload from SCM}" help="${rootUrl}/plugin/scm-sync-configuration/help/reloadScmConfig-branch-help.html">
<f:textbox id="scmBranchReloadTextId" name="scmBranchReload" value="${it.scmBranchReload}" />
</f:entry>

<f:entry title="${%}" help="${rootUrl}/plugin/scm-sync-configuration/help/reloadScmConfig-help.html">
<a id="reloadId" href="${rootURL}/plugin/scm-sync-configuration/reloadAllFilesFromScm" onClick="
if (confirm('${%WARNING : the Jenkins config will be reloaded from SCM Branch:}.\n${%Only file modifications are handled}. ${%File added or removed will not be handled} !\n${%All existing jobs will be removed} !\n\n${%Continue} ?') == true) {
document.getElementById('reloadId').href+='?scmBranchReload='+document.getElementById('scmBranchReloadTextId').value+'&amp;urlRepoReload='+document.getElementById('urlRepoReloadTextId').value;
} else {
return false;
}" >${%Reload}</a>
</f:entry>
</table>
</f:entry>
</f:section>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
<f:entry title="${%Repository URL}" help="${rootURL}/plugin/scm-sync-configuration/helpForRepositoryUrl?scm=${scm.id}">
<f:textbox id="gitRepositoryUrl" name="gitRepositoryUrl" value="${it.isScmSelected(scm) ? it.scmUrl : null}"/>
</f:entry>

<f:entry title="${%Repository branch}" help="${rootURL}/plugin/scm-sync-configuration/helpForRepositoryUrl?scm=${scm.id}">
<f:textbox id="scmGitBranch" name="scmGitBranch" value="${it.isScmSelected(scm) ? it.scmGitBranch : null}"/>
</f:entry>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@
description.1=\
Specify the git repository URL to synchronize your configuration files with, such as "[email protected]:mycompany/jenkins-config.git"
description.2=\
Note that, for the moment, your MUST reference your Git repository root
Specify branch name in branch field. If you leave it empty, master branch will be used. \
If you want to switch to new branch, just type it's name. If newly typed branch already contains any configuration, it will be merged with current one immediately after pressing "Save" button.
4 changes: 4 additions & 0 deletions src/main/webapp/help/reloadScmConfig-branch-help.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div>
A branch of repository which is source of configuration for reloading. <BR>
Please read help at "Reload" button for further help.
</div>
Loading

0 comments on commit 90f1e93

Please sign in to comment.