List <FileSystemPath> RecurseInteractiveDeleteDir(
            CommandEvaluationContext context,
            DirectoryPath dir,
            bool simulate,
            bool noattributes,
            bool verbose,
            CancellationTokenSource cancellationTokenSource)
        {
            var fullname = true;
            var r        = new List <FileSystemPath>();

            verbose |= simulate;
            if (cancellationTokenSource.IsCancellationRequested)
            {
                return(r);
            }
            if (dir.IsEmpty || Confirm("rm: descend " + dir.GetPrintableName(fullname)))
            {
                foreach (var subdir in dir.DirectoryInfo.EnumerateDirectories())
                {
                    r.Merge(RecurseInteractiveDeleteDir(context, new DirectoryPath(subdir.FullName), simulate, noattributes, verbose, cancellationTokenSource));
                }

                var options     = new FileSystemPathFormattingOptions(!noattributes, false, "", Br, -1, "removed ");
                var echoContext = new EchoEvaluationContext(context.Out, context, options);

                foreach (var subfile in dir.DirectoryInfo.EnumerateFiles())
                {
                    var subfi = new FilePath(subfile.FullName);
                    if (Confirm("rm: remove file " + subfi.GetPrintableName(fullname)))
                    {
                        if (!simulate)
                        {
                            subfi.FileSystemInfo.Delete();
                        }
                        if (verbose)
                        {
                            subfi.Echo(echoContext);
                        }
                        r.Add(subfi);
                    }
                }
                if (Confirm("rm: remove directory " + dir.GetPrintableName(fullname)))
                {
                    if (!simulate)
                    {
                        dir.DirectoryInfo.Delete(true);
                    }
                    if (verbose)
                    {
                        dir.Echo(echoContext);
                    }
                    r.Add(dir);
                }
            }
            return(r);
        }
        public CommandResult <DirectoryPath> Pwd(
            CommandEvaluationContext context,
            [Option("s", "short", "short display: do not print file system attributes")] bool noattributes
            )
        {
            var path = new DirectoryPath(Environment.CurrentDirectory);

            if (path.CheckExists(context))
            {
                path.Echo(new EchoEvaluationContext(context.Out, context, new FileSystemPathFormattingOptions(!noattributes, false, "", Br)));
                return(new CommandResult <DirectoryPath>(path));
            }
            else
            {
                return(new CommandResult <DirectoryPath>());
            }
        }
예제 #3
0
        public CommandVoidResult NewModule(
            CommandEvaluationContext context,
            [Parameter(0, "module ID")] string id,
            [Parameter(1, "module project repository url (if not set do net set project repository properties, thus the project repo is not connected to any remote repository)", true)] string repoUrl = null,
            [Option("o", "out", "output path", true, true)] DirectoryPath output = null,
            [Option("i", "in", "take parameters from json input file", true, true)] string inputFile = defaultSettingsFileName,
            [Option("f", "force", "delete target if already exists")] bool force                   = false,
            [Option("s", "skip-errors", "skip ant error if possible")] bool skipErrors             = false,
            [Option(null, "no-push", "don't perform an initial push of project repo")] bool noPush = false,
            [Option("project template url", "modproj-tpl-url", "module project template url", true, true)] string url = moduleProjectTemplateRepositoryUrl,
            [Option(null, "preserve-curdir", "preserve current dir")] bool preserveCurrentDir = false
            )
        {
            var o = context.Out;
            var c = context.ShellEnv.Colors;

            output ??= new DirectoryPath(Environment.CurrentDirectory);
            output = new DirectoryPath(Path.Combine(output.FullName, id));
            var input = new FilePath(inputFile);
            var ectx  = new EchoEvaluationContext(context);

            ectx.Options.LineBreak = true;
            CommandVoidResult result = CommandVoidResult.Instance;

            o.Echo(_title("shell module dotnet project generator"));

            #region download_pattern_project

            if (force && output.CheckExists())
            {
                Directory.Delete(output.FullName, true);
            }

            o.Echoln(_subTitle("cloning module project repository", url));
            o.Echo(_("into: ")); output.Echo(ectx); o.Echoln("(br)");

            if (!ShellExec(context, skipErrors, "git", $"clone {url} {output.FullName}", out result))
            {
                return(result);
            }

            #endregion

            #region setup project template properties

            if (!input.CheckExists(context))
            {
                return(new CommandVoidResult(ReturnCode.Error));
            }
            o.Echoln(_subTitle($"set project template properties", $"'{id}'"));

            string packageId = !string.IsNullOrWhiteSpace(repoUrl) ?
                               Path.GetFileNameWithoutExtension(repoUrl) : null;
            string repoOwner = !string.IsNullOrWhiteSpace(repoUrl) ?
                               Path.GetFileName(Path.GetDirectoryName(repoUrl)) : null;

            var settingsText = File.ReadAllText(input.FullName);
            var settings     = JsonConvert
                               .DeserializeObject <ModuleSettings>(settingsText)
                               .AutoFill(id, packageId);
            settings.ModuleRepositoryUrl   = repoUrl;
            settings.ModuleRepositoryOwner = repoOwner;

            o.Echoln(_subTitle("using settings", input.FullName));
            settings.Echo(ectx); o.Echoln("(br)");

            var items = fs.FindItems(
                context,
                output.FullName,
                "*",
                false,
                true,
                false,
                true,
                false,
                null,
                false,
                new FindCounts(),
                false);

            var fields = typeof(ModuleSettings).GetFields();
            foreach (var item in items)
            {
                var path = item.FullName;
                if (item.IsFile && fs.IsTextFile(path))
                {
                    var tpl = path;
                    _templateReplace(fields, settings, ref tpl);

                    var txt = File.ReadAllText(path);

                    if (tpl != path)
                    {
                        File.Delete(path);
                        path = tpl;
                    }

                    tpl = txt + "";
                    _templateReplace(fields, settings, ref tpl);
                    if (tpl != txt)
                    {
                        File.WriteAllText(path, tpl);
                    }
                }
            }

            void _deleteIfExists(string n)
            {
                if (File.Exists(n))
                {
                    File.Delete(n);
                }
            }

            _deleteIfExists(Path.Combine(output.FullName, "templateInfo.txt"));
            _deleteIfExists(Path.Combine(output.FullName, "./module-settings.json"));

            #endregion

            #region setup project repository

            o.Echoln(_subTitle("setup project repository", url)); o.Echoln();

            var curDir = Environment.CurrentDirectory;
            Environment.CurrentDirectory = output.FullName;

            if (!ShellExec(context, skipErrors, "git", "remote remove origin", out result))
            {
                return(result);
            }

            if (!string.IsNullOrWhiteSpace(settings.ModuleRepositoryUrl))
            {
                if (!ShellExec(context, skipErrors, "git", $"remote add origin {settings.ModuleRepositoryUrl}", out result))
                {
                    return(result);
                }
                // check this
                if (!noPush && !ShellExec(context, skipErrors, "git", "push --set-upstream origin main", out result))
                {
                    return(result);
                }
            }

            #endregion

            #region restore & build project

            o.Echoln(_subTitle("restore & build module project", "")); o.Echoln();

            if (!ShellExec(context, skipErrors, "dotnet", "build", out result))
            {
                return(result);
            }

            #endregion

            if (preserveCurrentDir)
            {
                Environment.CurrentDirectory = curDir;
            }

            o.Echoln(_subTitle($"module project has been generated", id));

            return(result ?? CommandVoidResult.Instance);
        }
예제 #4
0
        public CommandVoidResult NewModule(
            CommandEvaluationContext context,
            [Parameter(0, "module ID")] string id,
            [Parameter(1, "module project repository url (if not set do net set project repository properties, thus the project repo is not connected to any remote repository)", true)] string repoUrl = null,
            [Option("o", "out", "output path", true, true)] DirectoryPath output = null,
            [Option("i", "in", "take parameters from json input file", true, true)] string inputFile = defaultSettingsFileName,
            [Option("f", "force", "delete target if already exists")] bool force       = false,
            [Option("s", "skip-errors", "skip ant error if possible")] bool skipErrors = false,
            [Option(null, "no-git-init", "don't perform an initial init of the git repository - do not init the project as a git repository")] bool noInitRemote = false,
            [Option("project template url", "modproj-tpl-url", "module project template url", true, true)] string url             = moduleProjectTemplateRepositoryUrl,
            [Option("project archive url", "modproj-arch-url", "module project archive template url", true, true)] string archUrl = moduleProjectTemplateArchiveUrl,
            [Option(null, "preserve-curdir", "preserve current dir")] bool preserveCurrentDir = false
            )
        {
            var  o      = context.Out;
            var  c      = context.ShellEnv.Colors;
            bool noRepo = repoUrl == null;

            noInitRemote |= noRepo;
            string packageId = !string.IsNullOrWhiteSpace(repoUrl) ?
                               Path.GetFileNameWithoutExtension(repoUrl) : null;
            string repoOwner = !string.IsNullOrWhiteSpace(repoUrl) ?
                               Path.GetFileName(Path.GetDirectoryName(repoUrl)) : null;

            output ??= new DirectoryPath(Environment.CurrentDirectory);
            output = new DirectoryPath(Path.Combine(output.FullName, packageId ?? id));
            var targetId = packageId ?? id;
            var input    = new FilePath(inputFile);
            var ectx     = new EchoEvaluationContext(context);

            ectx.Options.LineBreak = true;
            CommandVoidResult result = CommandVoidResult.Instance;

            o.Echo(_title("shell module dotnet project generator"));

            #region download_pattern_project

            try
            {
                if (force && output.CheckExists())
                {
                    Directory.Delete(output.FullName, true);
                }
            } catch (Exception ex)
            {
                o.Errorln(ex.Message);
                if (!skipErrors)
                {
                    throw;
                }
            }

            o.Echoln(_subTitle("cloning module project repository", url));
            o.Echo(_("into: ")); output.Echo(ectx); o.Echoln("(br)");

            if (!noInitRemote)
            {
                // checkout repo
                if (!ShellExec(context, skipErrors, "git", $"clone {url} {output.FullName}", out result) && !skipErrors)
                {
                    return(result);
                }
            }
            else
            {
                // download & unpack as an archive
                o.Echoln(_subTitle("download project template archive", ""));
                var downloadArchRes = context.CommandLineProcessor.Eval(context, @$ "get " "{archUrl}" " -q -b");
                var archFile        = "tpl.zip";
                var res             = downloadArchRes.GetResult <HttpContentBody>();

                File.WriteAllBytes(
                    archFile,
                    (byte[])res.Content);

                if (File.Exists(archFile))
                {
                    _try(() =>
                    {
                        var arc  = ZipFile.OpenRead(archFile);
                        var root = arc.Entries.First();
                        arc.Dispose();
                        var rootName = root.FullName.Replace("/", "");
                        ZipFile.ExtractToDirectory(archFile, ".", true);
                        Directory.Move(rootName, targetId);
                        File.Delete(archFile);
                    });
                }
            }
            #endregion

            #region setup project template properties

            if (!input.CheckExists(context))
            {
                return(new CommandVoidResult(ReturnCode.Error));
            }
            o.Echoln(_subTitle($"set project template properties", $"'{id}'"));

            var settings = new ModuleSettings();

            _try(() =>
            {
                var settingsText = File.ReadAllText(input.FullName);
                var settings     = JsonConvert
                                   .DeserializeObject <ModuleSettings>(settingsText)
                                   .AutoFill(id, packageId);

                if (!noInitRemote)
                {
                    settings.ModuleRepositoryUrl   = repoUrl;
                    settings.ModuleRepositoryOwner = repoOwner;
                }

                o.Echoln(_subTitle("using settings", input.FullName));
                settings.Echo(ectx);
                o.Echoln("(br)");

                var items = fs.FindItems(
                    context,
                    output.FullName,
                    "*",
                    false,
                    true,
                    false,
                    true,
                    false,
                    null,
                    false,
                    new FindCounts(),
                    false);

                var fields = typeof(ModuleSettings).GetFields();
                foreach (var item in items)
                {
                    var path = item.FullName;
                    if (item.IsFile && FilePath.IsTextFile(path))
                    {
                        var tpl = path;
                        _templateReplace(fields, settings, ref tpl);

                        var txt = File.ReadAllText(path);

                        if (tpl != path)
                        {
                            _try(() => File.Delete(path));
                            path = tpl;
                        }

                        tpl = txt + "";
                        _templateReplace(fields, settings, ref tpl);
                        if (tpl != txt)
                        {
                            _try(() => File.WriteAllText(path, tpl));
                        }
                    }
                }
            });

            void _deleteIfExists(string n)
            {
                if (File.Exists(n))
                {
                    File.Delete(n);
                }
            }

            void _try(Action a)
            {
                try
                {
                    a();
                }
                catch (Exception ex)
                {
                    context.Error(ex.Message);
                    if (!skipErrors)
                    {
                        throw;
                    }
                }
            }

            _try(() =>
            {
                _deleteIfExists(Path.Combine(output.FullName, "templateInfo.txt"));
                _deleteIfExists(Path.Combine(output.FullName, "module-settings.json"));
            });

            #endregion

            #region setup project repository

            o.Echoln(_subTitle("setup project repository", url)); o.Echoln();

            var curDir = Environment.CurrentDirectory;
            _try(() => Environment.CurrentDirectory = output.FullName);

            if (!noInitRemote && !ShellExec(context, skipErrors, "git", "remote remove origin", out result) && !skipErrors)
            {
                return(result);
            }

            if (!string.IsNullOrWhiteSpace(settings.ModuleRepositoryUrl) && !noInitRemote)
            {
                if (!ShellExec(context, skipErrors, "git", $"remote add origin {settings.ModuleRepositoryUrl}", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "fetch", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "branch --set-upstream-to=origin/main main", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "pull --allow-unrelated-histories", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "add .", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "commit -a -m \"initial commit\"", out result) && !skipErrors)
                {
                    return(result);
                }
                if (!ShellExec(context, skipErrors, "git", "push", out result) && !skipErrors)
                {
                    return(result);
                }
            }

            #endregion

            #region restore & build project

            o.Echoln(_subTitle("restore & build module project", "")); o.Echoln();

            if (!ShellExec(context, skipErrors, "dotnet", "build", out result) && !skipErrors)
            {
                return(result);
            }

            #endregion

            if (preserveCurrentDir)
            {
                _try(() => Environment.CurrentDirectory = curDir);
            }

            o.Echoln(_subTitle($"module project has been generated", id));

            return(result ?? CommandVoidResult.Instance);
        }