internal void Lookup(string path, string pattern = "") { _gitRootDir = GitWorkTreeManager.GetGitRoot(Directory.GetCurrentDirectory()); if (string.IsNullOrEmpty(_gitRootDir)) { throw new DirectoryNotFoundException($"Cannot find a directory containing a .git directory or file."); } var ccdPath = Path.Combine(_gitRootDir, CcdDirectory); var lastPath = Path.Combine(ccdPath, LastFilename); var indexPath = Path.Combine(ccdPath, IndexFilename); if (File.Exists(lastPath) && path.Length < 3 && path.All(char.IsDigit)) { // here we have an small all digit parameter - less than 3-digits long. This is a reference to the "last" file var lastlines = File.ReadAllLines(lastPath); var separatorArray = new char[] { '|' }; foreach (var line in lastlines) { var segments = line.Split(separatorArray, StringSplitOptions.RemoveEmptyEntries); if (segments.Count() >= 2 && segments[0] == path) { Console.WriteLine($"#!cd {segments[1]}"); } } } else { if (!File.Exists(indexPath)) { throw new FileNotFoundException($"ccd index file not found - please run ccd -i first."); } // lookup the path in the index file and cd to it if its the only one. Otherwise print a numbered list of directories and store the list in the "last" file. // a subsequent ccd command with a number will interogate the last file: var dict = File.ReadAllLines(indexPath).Select(x => x.Split('|')).ToDictionary(y => y[0], y => y.Skip(1).ToList(), StringComparer.OrdinalIgnoreCase); if (dict.TryGetValue(path, out var pathList)) { ProcessList(pathList, pattern, lastPath); } else { // we found nothing - attempt a partial key search: var partialKeyMatches = dict.Keys.Where(x => x.StartsWith(path, StringComparison.InvariantCultureIgnoreCase)); if (partialKeyMatches.Any()) { pathList = dict[partialKeyMatches.First()]; ProcessList(pathList, pattern, lastPath); } } } }
public void Create() { _gitRootDir = GitWorkTreeManager.GetGitRoot(Directory.GetCurrentDirectory()); if (string.IsNullOrEmpty(_gitRootDir)) { throw new DirectoryNotFoundException($"Cannot find a directory containing a .git directory or file."); } var resultingIndex = new SortedDictionary <string, List <string> >(StringComparer.OrdinalIgnoreCase); var includes = _settings.GetList("include"); var excludes = _settings.GetList("exclude"); var dirStack = new Stack <string>(); dirStack.Push(_gitRootDir); while (dirStack.Any()) { var dir = dirStack.Pop(); var subDirs = Directory.GetDirectories(dir); foreach (var subDir in subDirs) { var name = new DirectoryInfo(subDir).Name; if (name.StartsWith(".") || name == "obj" || name.StartsWith("Deploy", StringComparison.OrdinalIgnoreCase)) { continue; } dirStack.Push(subDir); var relativeDir = PathExtensions.GetRelativePath(_gitRootDir, subDir); // if we have includes, then use them, otherwise include everything: if (includes.Any() && !includes.Any(x => relativeDir.StartsWith(x, StringComparison.OrdinalIgnoreCase))) { continue; } // split names with dots and spaces: if (name.Contains(".")) { var segments = name.Split('.'); foreach (var segment in segments) { DictUtils.AddEntryToList(resultingIndex, segment, relativeDir); } } if (name.Contains(" ")) { var segments = name.Split(' '); foreach (var segment in segments) { DictUtils.AddEntryToList(resultingIndex, segment, relativeDir); } } DictUtils.AddEntryToList(resultingIndex, name, relativeDir); } } var ccdPath = Path.Combine(_gitRootDir, CcdDirectory); Directory.CreateDirectory(ccdPath); var indexPath = Path.Combine(ccdPath, IndexFilename); using (var writer = new StreamWriter(indexPath)) { foreach (var entry in resultingIndex) { var matchingPaths = string.Join("|", entry.Value); writer.WriteLine($"{entry.Key}|{matchingPaths}"); } } }
private static void Main(string[] args) { try { var currentGitRoot = GitWorkTreeManager.GetGitRoot(Directory.GetCurrentDirectory()); var settings = new Settings(Path.Combine(currentGitRoot, ".ccd", "settings")); if (args.Length == 1 && args[0] == "-i") { var indexManager = new IndexManager(settings); indexManager.Create(); } else if (args.Any()) { var path = args[0]; if (Directory.Exists(path)) { Console.WriteLine($"#!cd {Utils.BashOrNot(path)}"); } else if (File.Exists(path)) { Console.WriteLine($"#!cd {Utils.BashOrNot(Path.GetDirectoryName(path))}"); } else if (path == "gl") { var gitWorktreeInfo = new GitWorkTreeManager(Directory.GetCurrentDirectory()); var worktrees = gitWorktreeInfo.WorkTrees; int count = 0; foreach (var worktree in worktrees) { Console.WriteLine($"{count++} {worktree.BranchName} {worktree.Directory} {worktree.Description}"); } } else if (path[0] == 'g' && path.Substring(1).All(char.IsDigit)) { var index = Int32.Parse(path.Substring(1)); var gitWorktreeInfo = new GitWorkTreeManager(Directory.GetCurrentDirectory()); var worktrees = gitWorktreeInfo.WorkTrees; if (index > worktrees.Length - 1) { throw new Exception($"index out of range - maximum is {worktrees.Length - 1}"); } var relpath = PathExtensions.GetRelativePath(currentGitRoot, Directory.GetCurrentDirectory()); var fullOtherPath = Path.Combine(worktrees[index].Directory, relpath); Console.WriteLine($"#!cd {Utils.BashOrNot(fullOtherPath)}"); } else if (path[0] == 'g' && int.TryParse(path.Substring(1, path.Length - 2), out var index) && char.IsLetter(path.Last())) { var gitWorktreeInfo = new GitWorkTreeManager(Directory.GetCurrentDirectory()); var worktrees = gitWorktreeInfo.WorkTrees; if (index > worktrees.Length - 1) { throw new Exception($"index out of range - maximum is {worktrees.Length - 1}"); } SubstMappingsHelper.CreateMapping(path.Last(), worktrees[index].Directory, deleteIfExisting: true); } else if (path[0] == 'g' && path.Last() == '-' && char.IsLetter(path[1])) { SubstMappingsHelper.DeleteMapping(path[1]); } else { var pattern = args.Length > 1 ? args[1] : string.Empty; var indexManager = new IndexManager(settings); indexManager.Lookup(path, pattern); } } } catch (Exception ex) { var fullname = System.Reflection.Assembly.GetEntryAssembly().Location; var progname = Path.GetFileNameWithoutExtension(fullname); Console.Error.WriteLine(progname + ": Error: " + ex.Message); } }