Example #1
0
            /// <summary>
            /// Ensures that the the Git Repository is opened and updates the <see cref="Worlds"/>.
            /// Returns true on success, false on error.
            /// </summary>
            /// <param name="m">The monitor to use.</param>
            /// <param name="force">True to refresh the <see cref="Worlds"/> even if <see cref="IsOpen"/> is already true.</param>
            /// <returns>Whether this repository has been successfully opened.</returns>
            internal bool Refresh(IActivityMonitor m, bool force = true)
            {
                bool isOpened = false;

                if (!IsOpen)
                {
                    _git = GitRepository.Create(m, this, Root, Root.LastPart, false, BranchName, checkOutBranchName: true);
                    if (_git == null)
                    {
                        return(false);
                    }
                    isOpened = true;
                }
                if (force || isOpened)
                {
                    if (_git.Pull(m, MergeFileFavor.Theirs).ReloadNeeded || isOpened)
                    {
                        var worldNames = Directory.GetFiles(Root, "*.World.xml")
                                         .Select(p => LocalWorldName.TryParse(p, _store.WorldLocalMapping))
                                         .Where(w => w != null)
                                         .ToDictionary(w => w.FullName);

                        var invalidParallels = worldNames.Values.Where(p => p.ParallelName != null && !worldNames.ContainsKey(p.Name)).ToList();
                        foreach (var orphan in invalidParallels)
                        {
                            m.Warn($"Invalid Parallel World '{orphan.FullName}': unable to find the default stack definition '{orphan.Name}' in the repository. It is ignored.");
                            worldNames.Remove(orphan.FullName);
                        }
                        foreach (var exists in _worlds)
                        {
                            if (!worldNames.Remove(exists.WorldName.FullName))
                            {
                                if (exists.WorldName.HasDefinitionFile)
                                {
                                    m.Warn($"Unable to find World definition file for '{exists.WorldName}'. File '{exists.WorldName.XmlDescriptionFilePath}' not found.");
                                    exists.WorldName.HasDefinitionFile = false;
                                }
                            }
                            else
                            {
                                if (!exists.WorldName.HasDefinitionFile)
                                {
                                    m.Trace($"Found World definition file for '{exists.WorldName}'.");
                                    exists.WorldName.HasDefinitionFile = true;
                                }
                            }
                        }
                        foreach (var newWorld in worldNames.Values)
                        {
                            m.Info($"Found a new World definition: creating '{newWorld.FullName}' entry.");
                            newWorld.HasDefinitionFile = true;
                            _worlds.Add(new WorldInfo(this, newWorld));
                        }
                    }
                }
                return(IsOpen);
            }
Example #2
0
            internal WorldInfo(StackRepo r, XElement e)
            {
                Repo = r;
                var n = (string)e.AttributeRequired(nameof(WorldName.FullName));

                _name = LocalWorldName.TryParse(r.Root.AppendPart(n + ".World.xml"), r.Store.WorldLocalMapping);
                _name.HasDefinitionFile = (bool?)e.Attribute(nameof(WorldName.HasDefinitionFile)) ?? false;
                _name.IsHidden          = (bool?)e.Attribute(nameof(WorldName.IsHidden)) ?? false;
            }
Example #3
0
        void OnWorkingFolderChanged(IActivityMonitor m, LocalWorldName local)
        {
            var repo = _repos.FirstOrDefault(r => local.XmlDescriptionFilePath.StartsWith(r.Root));

            if (repo == null)
            {
                m.Warn($"Unable to find the local repository for {local.FullName}.");
            }
            else if (!repo.IsOpen)
            {
                m.Warn($"Local repository {local.FullName} ({repo.Root}) is not opened.");
            }
            else
            {
                repo.PushChanges(m);
            }
        }
Example #4
0
        protected override LocalWorldName DoCreateNew(IActivityMonitor m, string name, string parallelName, XDocument content)
        {
            Debug.Assert(!String.IsNullOrWhiteSpace(name));
            Debug.Assert(content != null);
            Debug.Assert(parallelName == null || !String.IsNullOrWhiteSpace(parallelName));

            string wName = name + (parallelName != null ? '[' + parallelName + ']' : String.Empty);

            if (ReadWorlds(m).Any(w => w.FullName == wName))
            {
                m.Error($"World '{wName}' already exists.");
                return(null);
            }
            int idx = _stacks.IndexOf(d => d.StackName == name);

            if (idx < 0)
            {
                m.Error("A repository must be created first for a new Stack.");
                return(null);
            }
            var home = FindRepo(m, name);

            if (home == null)
            {
                return(null);
            }

            var path = home.Root.AppendPart(wName + ".World.xml");

            if (!File.Exists(path))
            {
                var w = new LocalWorldName(path, name, parallelName, WorldLocalMapping);
                if (!WriteWorldDescription(m, w, content))
                {
                    m.Error($"Unable to create {wName} world.");
                    return(null);
                }
                return(w);
            }
            m.Error($"World file {path} already exists.");
            return(null);
        }
Example #5
0
            internal void ReadWorlds(IActivityMonitor m, StackInitializeOption option, Action <LocalWorldName> addWorld)
            {
                if (option == StackInitializeOption.OpenRepository)
                {
                    EnsureOpen(m);
                }
                else if (option == StackInitializeOption.OpenAndPullRepository)
                {
                    Pull(m);
                }
                if (!IsOpen)
                {
                    m.Warn($"Repository '{OriginUrl}' for stacks '{_stacks.Select( s => s.StackName ).Concatenate("', '")}' is not opened. Skipping Worlds reading from them.");
                    return;
                }
                var worldNames = Directory.GetFiles(Root, "*.World.xml")
                                 .Select(p => LocalWorldName.TryParse(m, p, _store.WorldLocalMapping))
                                 .Where(w => w != null)
                                 .ToList();
                var missing = _stacks
                              .Where(s => !worldNames.Any(w => w.FullName.Equals(s.StackName, StringComparison.OrdinalIgnoreCase)));

                foreach (var s in missing)
                {
                    m.Warn($"Unable to find xml file definition for '{s.StackName}'.");
                }
                for (int i = 0; i < worldNames.Count; ++i)
                {
                    var w = worldNames[i];
                    if (w.ParallelName == null &&
                        !_stacks.Any(s => s.StackName.Equals(w.FullName, StringComparison.OrdinalIgnoreCase)))
                    {
                        m.Warn($"Unexpected '{w.FullName}' stack found. It is ignored.");
                        worldNames.RemoveAt(i--);
                    }
                    else
                    {
                        addWorld(w);
                    }
                }
            }
Example #6
0
        protected override LocalWorldName DoCreateNewParallel(IActivityMonitor m, IRootedWorldName source, string parallelName, XDocument content)
        {
            Debug.Assert(source != null);
            Debug.Assert(content != null);
            Debug.Assert(!String.IsNullOrWhiteSpace(parallelName));

            StackRepo repo = null;

            if (source is LocalWorldName src &&
                (repo = _stackRepos.FirstOrDefault(r => src.XmlDescriptionFilePath.StartsWith(r.Root))) == null)
            {
                m.Error($"Unable to find source World.");
                return(null);
            }
            string wName = source.Name + (parallelName != null ? '[' + parallelName + ']' : String.Empty);
            var    world = _stackRepos.SelectMany(r => r.Worlds).FirstOrDefault(w => w.WorldName.FullName == wName);

            if (world != null)
            {
                m.Error($"World '{wName}' already exists.");
                return(null);
            }

            var path = repo.Root.AppendPart(wName + ".World.xml");

            if (!File.Exists(path))
            {
                var w = new LocalWorldName(path, source.Name, parallelName, WorldLocalMapping);
                if (!WriteWorldDescription(m, w, content))
                {
                    m.Error($"Unable to create {wName} world.");
                    return(null);
                }
                return(w);
            }
            m.Error($"World file '{path}' already exists.");
            return(null);
        }
Example #7
0
 /// <summary>
 /// Destroys this WorldInfo: this deletes the Local file state (in the <see cref="IRootedWorldName.Root"/>), the shared file state
 /// and the definition file itself.
 /// Once done we remove this object from the <see cref="StackRepo.Worlds"/>.
 /// </summary>
 public bool Destroy(IActivityMonitor m)
 {
     if (_name != null)
     {
         var p = Repo.Store.ToLocalStateFilePath(WorldName);
         try
         {
             File.Delete(p);
             p = Repo.Store.ToSharedStateFilePath(WorldName).Item2;
             File.Delete(p);
             p = WorldName.XmlDescriptionFilePath;
             File.Delete(p);
             Repo.OnDestroy(this);
             _name.HasDefinitionFile = false;
             _name = null;
         }
         catch (Exception ex)
         {
             m.Error($"Unable to delete file '{p}'.", ex);
             return(false);
         }
     }
     return(true);
 }
Example #8
0
 internal WorldInfo(StackRepo repo, LocalWorldName name)
 {
     Debug.Assert(repo != null && name != null);
     Repo  = repo;
     _name = name;
 }