using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Net; using System.Threading; using System.Windows.Forms; using Microsoft.Build.Exceptions; using Microsoft.Build.Execution; using Microsoft.Build.Framework; using SharpSvn; namespace SvnForm { public partial class SvnMain : Form { SvnClient client = new SvnClient(); Semaphore trunkStatus = new Semaphore(0, 1); Semaphore branchStatus = new Semaphore(0, 1); Semaphore handle = new Semaphore(0, 1); private bool buildAborted = false; private Thread builder; private Thread build; public SvnMain() { InitializeComponent(); } #region event handlers private void SvnMain_Load(object sender, EventArgs e) { tbxUrl.Text = "http://dev.heuristiclab.com/svn/hl/core/"; tbxBranches.Text = "http://dev.heuristiclab.com/svn/hl/core/branches/"; tbxDir.Text = @"c:\dir"; gbxLogin.Hide(); lblSolutions.Text = "Which Solution" + Environment.NewLine + "to be build"; tbxPwd.Text = ""; tbxUsername.Text = ""; lbxConfiguration.SelectedIndex = 0; lbxPlatform.SelectedIndex = 0; lbxBranches.SelectionMode = SelectionMode.MultiSimple; LoadTreeView(); tabSvn.TabPages.Remove(tabProcess); tabSvn.TabPages.Remove(tabBuild); } private void btnLoad_Click(object sender, EventArgs e) { try { lbxBranches.Items.Clear(); string branchUrl = tbxBranches.Text; string uri = tbxUrl.Text; Collection contents; if (client.GetList(new Uri(branchUrl), out contents)) { foreach (SvnListEventArgs item in contents.Skip(1)) { //add from the Uri to listbox lbxBranches.Items.Add(item.Path); } } } catch { lbxBranches.Items.Add("The Url is not correct or Authentication needed to acces this Url"); } } private void btnDown_Click(object sender, EventArgs e) { if (lbxSolutions.SelectedIndex < lbxSolutions.Items.Count - 1) { String Temp = lbxSolutions.Items[lbxSolutions.SelectedIndex].ToString(); lbxSolutions.Items[lbxSolutions.SelectedIndex] = lbxSolutions.Items[lbxSolutions.SelectedIndex + 1]; lbxSolutions.Items[lbxSolutions.SelectedIndex + 1] = Temp; lbxSolutions.SelectedIndex++; // folow up by placing the selection again } } private void btnUp_Click(object sender, EventArgs e) { if (lbxSolutions.SelectedIndex > 0) { String Temp = lbxSolutions.Items[lbxSolutions.SelectedIndex].ToString(); lbxSolutions.Items[lbxSolutions.SelectedIndex] = lbxSolutions.Items[lbxSolutions.SelectedIndex - 1]; lbxSolutions.Items[lbxSolutions.SelectedIndex - 1] = Temp; lbxSolutions.SelectedIndex--; // folow up by placing the selection again } } private void btnBrowse_Click(object sender, EventArgs e) { if (folderBrowserDialog1.ShowDialog() == DialogResult.OK) { this.tbxDir.Text = folderBrowserDialog1.SelectedPath; } } private void btnFinish_Click(object sender, EventArgs e) { Application.Exit(); } private void btnNext_Click(object sender, EventArgs e) { tabSvn.TabPages.Remove(tabSvn.SelectedTab); tabSvn.TabPages.Add(tabProcess); Thread svn = new Thread(SvnTasks); svn.Start(); btnNext2.Enabled = false; Thread endSvn = new Thread(EndSvn); endSvn.Start(); } private void btnRefresh_Click(object sender, EventArgs e) { LoadTreeView(); } private void cbxAuthenticate_CheckedChanged(object sender, EventArgs e) { if (cbxAuthenticate.Checked) { gbxLogin.Show(); } else { gbxLogin.Hide(); } } private void trvBranches_AfterSelect(object sender, TreeViewEventArgs e) { string uri = tbxUrl.Text; if ((uri.Substring(uri.Length - Math.Min(1, uri.Length)) == "/")) { //to avoid double "//" i.e "http://xyz.com/files//abc//" on the Url uri = uri.Remove(uri.Length - 1); //e.g. dev.heuristiclab.com/svn/hl/core//branches/ } string val = trvBranches.SelectedNode.Text; if (trvBranches.SelectedNode.Parent == null) { tbxBranches.Text = uri + "/" + val + "/"; } else { string par = trvBranches.SelectedNode.Parent.Text; tbxBranches.Text = uri + "/" + par + "/" + val + "/"; } } private void trvSolution_AfterCheck(object sender, TreeViewEventArgs e) { if (e.Action != TreeViewAction.Unknown) { if (e.Node.Nodes.Count > 0) { /* Calls the CheckAllChildNodes method, passing in the current Checked value of the TreeNode whose checked state changed. */ this.CheckAllChildNodes(e.Node, e.Node.Checked); } } if (e.Node.Parent != null) { if (e.Node.Checked) { if (!lbxSolutions.Items.Contains(e.Node.Text)) { lbxSolutions.Items.Add(e.Node.Text); } } else { if (lbxSolutions.Items.Contains(e.Node.Text)) { lbxSolutions.Items.Remove(e.Node.Text); } } } if (lbxSolutions.Items.Count > 0) { btnNext2.Enabled = true; } } private void btnBack_Click(object sender, EventArgs e) { tabSvn.TabPages.Add(tabMain); tabSvn.TabPages.Remove(tabSvn.SelectedTab); } private void btnNext2_Click(object sender, EventArgs e) { buildLogTextBox.Clear(); tabSvn.TabPages.Add(tabBuild); tabSvn.TabPages.Remove(tabSvn.SelectedTab); build = new Thread(BuildAll); build.Start(); ShowProgressBar(); DisableButton(); } private void btnBack2_Click(object sender, EventArgs e) { tabSvn.TabPages.Add(tabProcess); tabSvn.TabPages.Remove(tabSvn.SelectedTab); BuildManager.DefaultBuildManager.CancelAllSubmissions(); } private void btnCancel_Click(object sender, EventArgs e) { Application.Exit(); } #endregion #region Invoke private void ShowProgressBar() { if (InvokeRequired) { MethodInvoker AssignMethodToControl = new MethodInvoker(ShowProgressBar); prbSvn.Invoke(AssignMethodToControl); prbBuild.Invoke(AssignMethodToControl); } else { prbSvn.Show(); prbBuild.Show(); prbSvn.Style = ProgressBarStyle.Marquee; prbBuild.Style = ProgressBarStyle.Marquee; } } private void HideProgressBar() { if (InvokeRequired) { MethodInvoker AssignMethodToControl = new MethodInvoker(HideProgressBar); prbSvn.Invoke(AssignMethodToControl); } else { prbSvn.Hide(); } } private void HidePrbBuild() { if (InvokeRequired) { MethodInvoker AssignMethodToControl = new MethodInvoker(HidePrbBuild); prbBuild.Invoke(AssignMethodToControl); } else { prbBuild.Hide(); } } private void UpdatelblStatus(string message) { if (lblStatus.InvokeRequired) { lblStatus.Invoke(new Action(UpdatelblStatus), message); } else { lblStatus.Text = message; } } private void UpdateBuildSln(string message) { if (InvokeRequired) { Invoke(new Action(UpdateBuildSln), message); } else lblBuild.Text = message; } private void HidegbxBuild() { if (gbxBuild.InvokeRequired) { gbxBuild.Invoke(new MethodInvoker(HidegbxBuild)); } else { gbxBuild.Hide(); } } private void ShowgbxBuild() { if (gbxBuild.InvokeRequired) { gbxBuild.Invoke(new MethodInvoker(ShowgbxBuild)); } else { gbxBuild.Show(); } } private void UpdatelbxBranches() { if (lbxBranches.InvokeRequired) { MethodInvoker AssignMethodToControl = new MethodInvoker(UpdatelbxBranches); lbxBranches.Invoke(AssignMethodToControl); } else { lbxBranches.SelectedItems.ToString(); } } private void EnableButton() { if (btnFinish.InvokeRequired) { MethodInvoker AssignMethodToControl = new MethodInvoker(EnableButton); btnFinish.Invoke(AssignMethodToControl); } else { btnFinish.Enabled = true; } } private void DisableButton() { if (btnFinish.InvokeRequired) { MethodInvoker AssignMethodToControl = new MethodInvoker(DisableButton); btnFinish.Invoke(AssignMethodToControl); } else { btnFinish.Enabled = false; } } public void AppendTextToBuildLog(string message) { if (InvokeRequired) { this.Invoke(new Action(AppendTextToBuildLog), message); } else { buildLogTextBox.AppendText(message); } } public void Login(string usrName, string password) { client.Authentication.Clear(); client.Authentication.DefaultCredentials = new NetworkCredential(usrName, password); } #endregion #region treeview methods private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked) { foreach (TreeNode node in treeNode.Nodes) { node.Checked = nodeChecked; if (node.Nodes.Count > 0) { // If the current node has child nodes, call the CheckAllChildsNodes method recursively. this.CheckAllChildNodes(node, nodeChecked); } } } private void LoadTreeView() { try { trvBranches.Nodes.Clear(); string branchUrl = tbxBranches.Text; TreeNode node = new TreeNode(); string uri = tbxUrl.Text; if ((uri.Substring(uri.Length - Math.Min(1, uri.Length)) != "/")) { uri = uri + "/"; } Collection contents; Collection childContents; Login(tbxUsername.Text, tbxPwd.Text); if (client.GetList(new Uri(uri), out contents)) { foreach (SvnListEventArgs item in contents.Skip(1)) { node = new TreeNode(item.Path); trvBranches.Nodes.Add(node); if (client.GetList(new Uri(uri + item.Path), out childContents)) { foreach (SvnListEventArgs items in childContents.Skip(1)) { node.Nodes.Add(items.Path); } } } } } catch { lbxBranches.Items.Clear(); lbxBranches.Items.Add("The Url is not correct or Authentication needed to acces this Url"); } } private void LoadSolutionsTreeView() { if (tbxDir.InvokeRequired) { tbxDir.Invoke(new Action(LoadSolutionsTreeView)); } else { trvSolution.Nodes.Clear(); string dir = tbxDir.Text; string[] solutions = { "trunk", "branches" }; TreeNode node = new TreeNode(); foreach (string sol in solutions) { node = new TreeNode(sol); trvSolution.Nodes.Add(node); if (sol == "trunk") { foreach (string filName in (Directory.GetFiles(dir + @"\" + sol + @"\sources", "*.sln"))) { node.Nodes.Add(filName); } } else { foreach (string filName in (Directory.GetFiles(dir + @"\" + sol, "*.sln", SearchOption.AllDirectories))) { node.Nodes.Add(filName); } } } trvSolution.ExpandAll(); } } #endregion #region svnTasks private void SvnTasks() { try { HidegbxBuild(); if (lbxBranches.InvokeRequired) { lbxBranches.Invoke(new Action(SvnTasks)); } else { ShowProgressBar(); Thread tr = new Thread(new ThreadStart(SvnTrunk)); Thread ch = new Thread(CheckoutBranches); tr.IsBackground = true; ch.IsBackground = true; tr.Start(); ArrayList lstSelItems = new ArrayList(); UpdatelbxBranches(); for (int i = 0; i < lbxBranches.SelectedItems.Count; i++) { lstSelItems.Add(lbxBranches.SelectedItems[i]); } ch.Start(lstSelItems); if (tr.IsAlive || ch.IsAlive) { ShowProgressBar(); } else { HideProgressBar(); } UpdatelblStatus("Cleaning and Updating the directory... "); } } catch (Exception e) { UpdatelblStatus(e.Message); } } public void SvnTrunk() { try { SvnClient client = new SvnClient(); string trunk = tbxUrl.Text + "/trunk"; string dir = tbxDir.Text; if (System.IO.Directory.Exists(dir + @"\trunk\")) { client.CleanUp(Path.Combine(dir, @"\trunk")); SvnUpdateResult r; client.Update(dir + @"\trunk\", out r); } else { client.CheckOut(new Uri(trunk), dir + @"\trunk"); } } catch (Exception e) { UpdatelblStatus(e.Message); } trunkStatus.Release(); } public void CheckoutBranches(object selectedItems) { try { string branches = tbxBranches.Text; string dir = tbxDir.Text; if (!Directory.Exists(dir + @"\branches\")) { Directory.CreateDirectory(dir + @"\branches\"); } UpdatelbxBranches(); foreach (Object selectedItem in (ArrayList)selectedItems) { String br; br = selectedItem as String; if (!System.IO.Directory.Exists(dir + @"\branches\" + br)) { client.CheckOut(new Uri(branches + br), dir+ @"\branches\"+ br); } else { client.CleanUp(dir + @"\branches\" + br + "\\"); SvnUpdateResult r; client.Update(dir + @"\branches\" + br + "\\", out r); } } } catch (Exception e) { UpdatelblStatus(e.Message); } branchStatus.Release(); } private void EndSvn() { trunkStatus.WaitOne(); branchStatus.WaitOne(); UpdatelblStatus(""); HideProgressBar(); ShowgbxBuild(); Thread solTree = new Thread(LoadSolutionsTreeView); solTree.Start(); } #endregion #region Build Solution private void Build(string fileName) { if (InvokeRequired) { Invoke(new Action(Build), fileName); } else { try { BuildLogger bl = new BuildLogger(this); List blList = new List(); blList.Add(bl); string dir = tbxDir.Text.ToString(); string config = lbxConfiguration.SelectedItem.ToString(); string platform = lbxPlatform.SelectedItem.ToString(); var GlobalProperty = new Dictionary(); GlobalProperty.Add("Configuration", config); GlobalProperty.Add("Platform", platform); BuildManager.DefaultBuildManager.BeginBuild(new BuildParameters() { DetailedSummary = false, Loggers = blList }); BuildRequestData request = new BuildRequestData(fileName, GlobalProperty, null, new string[] { "Build" }, null); BuildSubmission submission = BuildManager.DefaultBuildManager.PendBuildRequest(request); submission.ExecuteAsync(BuildCompletedCallback, null); } catch (Exception e) { UpdatelblStatus(e.Message); } } } private void BuildCompletedCallback(BuildSubmission submission) { BuildManager.DefaultBuildManager.EndBuild(); if (submission.BuildResult.Exception is BuildAbortedException) { buildAborted = true; } handle.Release(); } private void BuildAll() { List files = new List(); foreach (string file in lbxSolutions.Items) files.Add(file); foreach (string file in files) { builder = new Thread(() => Build(file)); builder.Start(); UpdateBuildSln("Building " + file); handle.WaitOne(); if (buildAborted) { buildAborted = false; break; } } UpdateBuildSln("Finished building"); HidePrbBuild(); EnableButton(); } #endregion } }