/// <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); }
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; }
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); } } }