Example #1
0
        /// <summary>
        /// Pushes the version taken as a parameter
        /// Will return any changes that conflicts
        /// IMPORTANT: The version is not commited at the server before null is returned!
        /// </summary>
        /// <param name="path">The path to the repository to push</param>
        /// <param name="number">The version number used to identify the right version</param>
        /// <param name="log">The changes given by a number of text-.</param>
        /// <param name="user">The user to submit changes.</param>
        /// <returns>
        /// Any changes that conflicts or null if version is commited
        /// </returns>
        /// <exception cref="System.ArgumentNullException">Log can't be null</exception>
        /// <exception cref="System.ArgumentException">Log can't be empty</exception>
        public string[][] PushVersion(String path, int number, string[] log, User user)
        {
            if (log == null) throw new ArgumentNullException("Log can't be null");
            if (log.Length < 1) throw new ArgumentException("Log can't be empty");
            if (user == null) throw new ArgumentNullException("User can't be null");
            if (String.IsNullOrEmpty(user.Name)) throw new ArgumentException("User's name is invalid: " + user.Name);
            if (String.IsNullOrEmpty(user.Password)) throw new ArgumentException("User's password is invalid");
            if (user.MAC == null) throw new ArgumentNullException("User's MAC address is invalid (" + user.MAC + " and can therefore not push");

            Console.WriteLine("[" + DateTime.Now + "]: " + "User is pushing to the server: " + user.MAC);

            //See if the user is known - if not: Throw an exception
            //Connect(user);

            var returnArray = new string[0][];

            // Test that the version number is correct - otherwise we'll just store things at the wrong places.
            var vcs = new ServerVersionControlSystem(path, _fileSystem);
            var currentVersion = vcs.GetLatestVersionNumber();
            if (currentVersion != number - 1)
            {
                throw new ArgumentException("Can not push version " + number + " to the server version " + currentVersion);
            }

            // If the last user that attempted to push is the same as the current user, no conflicts will occur.
            if (PushedLastVersion(user))
            {
                // We can assume that everything has been resolved client side and execute all the changes made
                IList<AbstractChange> changeList = ChangeParser.ParseChanges(log).Where(item => item != null).ToList();

                // Store the version
                SaveChanges(number, user, vcs, changeList);
            }
            else
            {
                String[] simpleChanges = SearchForSimpleChanges(log);
                String[,] complexChanges = SearchForComplexChanges(log);
                ISet<String> conflictingPathsOnServerSet = new SortedSet<string>();
                ISet<String> conflictingPathsOnClientSet = new SortedSet<string>();

                //Get paths to all text files in project directory and all sub directories.
                String absolutePath = vcs.GetFileSystemRoot() + path;
                IList<String> projectFilesList = new List<string>(Directory.GetFileSystemEntries(absolutePath, "*", SearchOption.AllDirectories).Where(s => s.Contains(FileSystem.META_DIR) == false));

                // Discover potential conflicts
                for (int i = 0; i < projectFilesList.Count; i++)
                {
                    projectFilesList[i] = projectFilesList[i].Substring(vcs.GetFileSystemRoot().Length);
                }

                foreach (String filePath in simpleChanges)
                {
                    if (projectFilesList.Contains(filePath))
                    {
                        conflictingPathsOnServerSet.Add(filePath);
                        conflictingPathsOnClientSet.Add(filePath);
                    }
                }
                for (int i = 0; i < complexChanges.Length; i++)
                {
                    if (projectFilesList.Contains(complexChanges[i, 0]))
                    {
                        conflictingPathsOnServerSet.Add(complexChanges[i, 0]);
                        conflictingPathsOnClientSet.Add(complexChanges[i, 1]);
                    }
                }

                // If no conflicts arises we can save the change to the file system
                if (conflictingPathsOnServerSet.Count == 0)
                {
                    SaveChanges(number, user, vcs, ChangeParser.ParseChanges(log));
                }
                else // Otherwise we find the conflicting paths and return the contents of the file on the
                // server for the client to merge
                {
                    IList<String> conflictingPathsOnServer = new List<string>(conflictingPathsOnServerSet);
                    IList<String> conflictingPathsOnClient = new List<string>(conflictingPathsOnClientSet);
                    var list = new List<string[]>();
                    for (int i = 0; i < conflictingPathsOnServer.Count; i++)
                    {
                        var fileList = new List<string>() { conflictingPathsOnClient[i] };
                        fileList.AddRange(vcs.ReadAllLines(conflictingPathsOnServer[i]));
                        list.Add(fileList.ToArray());
                    }
                    returnArray = list.ToArray();
                }
            }

            // Save the last MAC adress
            _lastPushUser = user.Name;
            //AddToPushHistory(user);

            // Return the conflicts to the client
            return returnArray;
        }
Example #2
0
 /// <summary>
 /// Get the logs containing changes for the specified versions
 /// </summary>
 /// <param name="path">The relative path to the project root</param>
 /// <param name="from">The version number from</param>
 /// <param name="to">The version number to</param>
 /// <returns></returns>
 public String[][] GetVersions(String path, int from, int to)
 {
     var vcs = new ServerVersionControlSystem(path, _fileSystem);
     IEnumerable<int> enu = Enumerable.Range(from, to - from + 1);
     IEnumerable<String[]> esu = enu.Select(vcs.GetVersionLog);
     return new List<string[]>(esu).ToArray();
 }