Exemplo n.º 1
0
        /// <summary>
        /// Whether the driver support the specified uri.
        /// </summary>
        /// <param name="io">The input/output instance.</param>
        /// <param name="config">The config instance.</param>
        /// <param name="uri">Thr specified uri.</param>
        /// <param name="deep">Whether is deep checker.</param>
        /// <returns>True if the driver is supported.</returns>
        public static bool IsSupport(IIO io, Config config, string uri, bool deep = false)
        {
            if (Regex.IsMatch(uri, @"(^git://|\.git/?$|git(?:olite)?@|//git\.|//github\.com/|//gitlib\.com/)", RegexOptions.IgnoreCase))
            {
                return(true);
            }

            bool ProcessCheck(string command, string cwd)
            {
                var process = new BucketProcessExecutor(io);

                return(process.Execute(command, cwd) == 0);
            }

            if (FileSystemLocal.IsLocalPath(uri))
            {
                uri = FileSystemLocal.GetPlatformPath(uri);
                if (!Directory.Exists(uri))
                {
                    return(false);
                }

                return(ProcessCheck("git tag", uri));
            }

            if (!deep)
            {
                return(false);
            }

            return(ProcessCheck($"git ls-remote --heads {ProcessExecutor.Escape(uri)}", null));
        }
Exemplo n.º 2
0
 /// <inheritdoc />
 public virtual void Copy(string uri, string target, IProgress <ProgressChanged> progress = null, IReadOnlyDictionary <string, object> additionalOptions = null)
 {
     FileSystemLocal.EnsureDirectory(Directory.GetParent(target).FullName);
     using (var saved = new FileStream(target, FileMode.CreateNew, FileAccess.Write, FileShare.None, buffer.Length))
     {
         GetRequest(uri, saved, progress, additionalOptions);
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// Copy a local file into the cache.
        /// </summary>
        /// <param name="cache">The cache system instance.</param>
        /// <param name="file">The cache file name.</param>
        /// <param name="source">The source file absolute path.</param>
        /// <returns>True if the copy successful.</returns>
        public static bool CopyFrom(this ICache cache, string file, string source)
        {
            if (!cache.Enable)
            {
                return(false);
            }

            var local = new FileSystemLocal();

            using (var stream = local.Read(source))
            {
                cache.Write(file, stream);
            }

            return(true);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Copy a file out of the cache to local disk.
        /// </summary>
        /// <param name="cache">The cache system instance.</param>
        /// <param name="file">The cache file name.</param>
        /// <param name="target">Absolute path to the local disk.</param>
        /// <returns>True if the copy successful.</returns>
        public static bool CopyTo(this ICache cache, string file, string target)
        {
            if (!cache.Enable)
            {
                return(false);
            }

            var local = new FileSystemLocal();

            using (var stream = cache.Read(file))
            {
                local.Write(target, stream);
            }

            return(true);
        }
Exemplo n.º 5
0
        public void Initialize()
        {
            root       = Helper.GetTestFolder <TestsFileSystemLocal>();
            fileSystem = new FileSystemLocal(root);

            if (Directory.Exists(root))
            {
                Directory.Delete(root, true);
            }

            if (File.Exists(root))
            {
                File.Delete(root);
            }

            Directory.CreateDirectory(root);
        }
Exemplo n.º 6
0
        /// <inheritdoc />
        public override void Initialize()
        {
            string cacheUri;

            if (FileSystemLocal.IsLocalPath(Uri))
            {
                Uri = Regex.Replace(Uri, @"[\\/]\.git/?$", string.Empty);
                repositoryDirectory = Uri;
                cacheUri            = Path.GetFullPath(Uri);
            }
            else
            {
                var cacheVcsDir = Config.Get(Settings.CacheVcsDir);
                if (!CacheFileSystem.IsUsable(cacheVcsDir))
                {
                    throw new RuntimeException("DriverGit requires a usable cache directory, and it looks like you set it to be disabled.");
                }

                if (Regex.IsMatch("^ssh://[^@]+@[^:]+:[^0-9]+", Uri))
                {
                    throw new InvalidArgumentException($"The source URL {Uri} is invalid, ssh URLs should have a port number after \":\".{Environment.NewLine}Use ssh://[email protected]:22/path or just [email protected]:path if you do not want to provide a password or custom port.");
                }

                Git.CleanEnvironment();

                var fileSystem = new FileSystemLocal($"{cacheVcsDir}/{CacheFileSystem.FormatCacheFolder(Uri)}/");
                var git        = new Git(IO, Config, Process, fileSystem);

                repositoryDirectory = fileSystem.Root;

                if (!git.SyncMirror(Uri, repositoryDirectory))
                {
                    IO.WriteError($"<error>Failed to update {Uri}, package information from this repository may be outdated</error>");
                }

                cacheUri = Uri;
            }

            GetTags();
            GetBranches();

            cache = new CacheFileSystem($"{Config.Get(Settings.CacheRepoDir)}/{CacheFileSystem.FormatCacheFolder(cacheUri)}", IO);
        }
Exemplo n.º 7
0
        /// <summary>
        /// extract <paramref name="file"/> to <paramref name="extractPath"/> with unzip command.
        /// </summary>
        protected internal virtual void ExtractWithUnzipCommand(string file, string extractPath, bool isFallback = false)
        {
            // When called after a ZipArchive failed, perhaps
            // there is some files to overwrite
            var overwrite = isFallback ? "-o " : string.Empty;
            var command   = $"unzip -qq {overwrite}{ProcessExecutor.Escape(file)} -d {ProcessExecutor.Escape(extractPath)}";

            FileSystemLocal.EnsureDirectory(extractPath);

            SException processException;

            try
            {
                if (process.Execute(command, out _, out string stderr) == 0)
                {
                    return;
                }

                throw new RuntimeException(
                          $"Failed to execute {command} {Environment.NewLine}{Environment.NewLine} {stderr}");
            }
#pragma warning disable CA1031
            catch (SException ex)
#pragma warning restore CA1031
            {
                processException = ex;
            }

            if (isFallback)
            {
                ExceptionDispatchInfo.Capture(processException).Throw();
            }

            io.WriteError($"    {processException.Message}");
            io.WriteError($"    The archive may contain identical file names with different capitalization (which fails on case insensitive filesystems)");
            io.WriteError($"    Unzip with unzip command failed, falling back to {nameof(ZipArchive)}.");

            ExtractWithZipArchive(file, extractPath, true);
        }
Exemplo n.º 8
0
        private void ProcessAction(string[] sourceUris, Action <string> closure)
        {
            var uris = new Queue <string>(sourceUris);

            Guard.Requires <UnexpectedException>(uris.Count > 0, "The number of valid download addresses must be greater than 0.");

            while (uris.Count > 0)
            {
                var uri = uris.Dequeue();

                try
                {
                    if (FileSystemLocal.IsLocalPath(uri))
                    {
                        uri = ProcessLocalSourceUri(uri);
                    }

                    closure(uri);
                    break;
                }
                catch (SException ex)
                {
                    if (IO.IsDebug)
                    {
                        IO.WriteError($"Failed: [{ex.GetType()}] {ex.Message}");
                    }
                    else if (uris.Count > 0)
                    {
                        IO.WriteError("    Failed, trying the next URI");
                    }

                    if (uris.Count <= 0)
                    {
                        throw;
                    }
                }
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Transfer the permissions of the source file(or dir) to the target file(or dir).
        /// </summary>
        /// <remarks>It is not allowed to pass permissions between folders and files, this will return false.</remarks>
        /// <returns>True if transfer successful. false if the <paramref name="destination"/> not exists.</returns>
        public static bool TransferPerms(string source, string destination)
        {
            if (!FileSystem.Exists(source) || !FileSystem.Exists(destination))
            {
                return(false);
            }

            var sourceIsDir      = FileSystemLocal.IsDirectory(source);
            var destinationIsDir = FileSystemLocal.IsDirectory(destination);

            // Ensure source is same type for the destination.
            if (sourceIsDir != destinationIsDir)
            {
                return(false);
            }

            if (Platform.IsWindows)
            {
                return(PermissionWindows.TransferPerms(source, destination, sourceIsDir));
            }

            return(PermissionUnix.TransferPerms(source, destination));
        }
Exemplo n.º 10
0
        /// <inheritdoc />
        public override void Install(IPackage package, string cwd, bool output)
        {
            if (output)
            {
                io.WriteError($"  - Installing <info>{package.GetName()}</info> (<comment>{package.GetVersionPrettyFull()}</comment>): Extracting archive");
            }
            else
            {
                io.WriteError("Extracting archive", false);
            }

            fileSystem.Delete(cwd);

            var temporaryDir = Path.Combine(
                GetTempDirectory(),
                "extract",
                Security.Md5(Guid.NewGuid().ToString()).Substring(0, 7));

            var downloadedFilePath = GetDownloadedFilePath(package, cwd);

            try
            {
                FileSystemLocal.EnsureDirectory(temporaryDir);

                try
                {
                    Extract(package, downloadedFilePath, temporaryDir);
                }
                catch
                {
                    // remove cache if the file was corrupted.
                    ClearLastCacheWrite(package);
                    throw;
                }

                // Expand a single top-level directory for a
                // better experience.
                string ExtractSingleDirAtTopLevel(string path)
                {
                    var contents = fileSystem.GetContents(path);
                    var files    = contents.GetFiles();
                    var dirs     = contents.GetDirectories();

                    files = Arr.Filter(files, (file) => !file.EndsWith(".DS_Store", StringComparison.Ordinal));

                    if ((dirs.Length + files.Length) != 1 || files.Length == 1)
                    {
                        return(path);
                    }

                    return(ExtractSingleDirAtTopLevel(dirs[0]));
                }

                fileSystem.Move(ExtractSingleDirAtTopLevel(temporaryDir), cwd);
            }
            catch
            {
                fileSystem.Delete(cwd);
                throw;
            }
            finally
            {
                fileSystem.Delete(temporaryDir);
                fileSystem.Delete(downloadedFilePath);
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Create a new <see cref="DownloadManager"/> instance.
        /// </summary>
        /// <param name="io">The input/output instance.</param>
        /// <param name="config">The config instance.</param>
        /// <param name="transport">The transport instance.</param>
        /// <param name="eventDispatcher">The event dispatcher instance.</param>
        public static DownloadManager CreateManager(IIO io, Config config, ITransport transport = null, IEventDispatcher eventDispatcher = null)
        {
            var manager = new DownloadManager(io);

            InstallationSource GetInstallationSource(string prefer)
            {
                switch (prefer ?? "auto")
                {
                case "dist":
                    return(InstallationSource.Dist);

                case "source":
                    return(InstallationSource.Source);

                case "auto":
                default:
                    return(InstallationSource.Auto);
                }
            }

            try
            {
                var prefer = GetInstallationSource(config.Get(Settings.PreferredInstall));
                switch (prefer)
                {
                case InstallationSource.Dist:
                    manager.SetPreferDist();
                    break;

                case InstallationSource.Source:
                    manager.SetPreferSource();
                    break;

                default:
                    break;
                }
            }
            catch (ConfigException)
            {
                // Maybe the developer is using fine configuration.
                var preferred = config.Get <ConfigPreferred>(Settings.PreferredInstall);
                manager.SetPreferences(Arr.Map(preferred, (item) => (item.Key, GetInstallationSource(item.Value))));
            }

            transport = transport ?? new TransportHttp(io, config);
            var process    = new BucketProcessExecutor(io);
            var fileSystem = new FileSystemLocal(process: process);

            ICache cache = null;

            if (config.Get(Settings.CacheFilesTTL) > 0)
            {
                cache = new CacheFileSystem(config.Get(Settings.CacheFilesDir), io, "a-z0-9_./", fileSystem);
            }

            manager.SetDownloader("git", new DownloaderGit(io, config, process, fileSystem));
            manager.SetDownloader("zip", new DownloaderZip(io, config, transport, eventDispatcher, cache, fileSystem, process));
            manager.SetDownloader("file", new DownloaderFile(io, config, transport, eventDispatcher, cache, fileSystem));

            return(manager);
        }
Exemplo n.º 12
0
        public void TestAltDirectorySeparatorChar()
        {
            var foo = new FileSystemLocal("c:/folder/foo");

            Assert.AreNotEqual(null, foo);
        }
Exemplo n.º 13
0
 public void TestIsLocalPath(bool expected, string path)
 {
     Assert.AreEqual(expected, FileSystemLocal.IsLocalPath(path));
 }
Exemplo n.º 14
0
        /// <summary>
        /// Creates a <see cref="Bucket"/> object from specified <paramref name="cwd"/>.
        /// </summary>
        /// <remarks>If no <paramref name="cwd"/> is given, the current environment path will be used.</remarks>
        /// <param name="io">The input/output instance.</param>
        /// <param name="localBucket">either a configuration filename to read from, if null it will read from the default filename.</param>
        /// <param name="disablePlugins">Whether plugins should not be loaded.</param>
        /// <param name="cwd">Current working directory.</param>
        /// <param name="fullLoad">Whether to initialize everything or only main project stuff (used when loading the global bucket and auth).</param>
        /// <exception cref="InvalidArgumentException">If local config file not exists.</exception>
        public Bucket CreateBucket(IIO io, object localBucket = null, bool disablePlugins = false, string cwd = null, bool fullLoad = true)
        {
            cwd = cwd ?? Environment.CurrentDirectory;
            var    localFileSystem = new FileSystemLocal(cwd);
            var    config          = CreateConfig(io, cwd);
            string bucketFile      = null;

            if (localBucket == null || localBucket is string)
            {
                bucketFile = localBucket?.ToString();
                bucketFile = string.IsNullOrEmpty(bucketFile) ? GetBucketFile() : bucketFile;

                var localBucketFile = new JsonFile(bucketFile, localFileSystem, io);
                if (!localBucketFile.Exists())
                {
                    string message;
                    if (bucketFile == "./bucket.json" || bucketFile == "bucket.json")
                    {
                        message = $"Bucket could not find a bucket.json file in {cwd}";
                    }
                    else
                    {
                        message = $"Bucket could not find the config file {bucketFile} in {cwd}";
                    }

                    var instructions = "To initialize a project, please create a bucket.json";
                    throw new InvalidArgumentException(message + Environment.NewLine + instructions);
                }

                localBucketFile.Validate(false);

                io.WriteError($"Loading bucket file: {localBucketFile.GetPath()}", true, Verbosities.Debug);
                config.Merge(localBucketFile.Read());
                config.SetSourceBucket(new JsonConfigSource(localBucketFile));

                var localAuthFile = new JsonFile("./auth.json", localFileSystem, io);
                if (localAuthFile.Exists())
                {
                    io.WriteError($"Loading bucket file: {localAuthFile.GetPath()}", true, Verbosities.Debug);
                    config.Merge(new JObject
                    {
                        ["config"] = localAuthFile.Read(),
                    });
                    config.SetSourceAuth(new JsonConfigSource(localAuthFile, true));
                }

                localBucket = localBucketFile.Read <ConfigBucket>();
            }
            else if (localBucket is ConfigBucket configBucket)
            {
                config.Merge(JObject.FromObject(configBucket));
            }
            else
            {
                throw new UnexpectedException($"Params \"{localBucket}\" only allow {nameof(ConfigBucket)} type or string path.");
            }

            if (fullLoad)
            {
                new LoaderIOConfiguration(io).Load(config);
            }

            // initialize bucket.
            var bucket = new Bucket();

            bucket.SetConfig(config);

            var transport = CreateTransport(io, config);

            // initialize event dispatcher.
            var dispatcher = new BEventDispatcher(bucket, io);

            bucket.SetEventDispatcher(dispatcher);

            // initialize repository manager
            var repositoryManager = RepositoryFactory.CreateManager(io, config, dispatcher);

            bucket.SetRepositoryManager(repositoryManager);

            InitializeLocalInstalledRepository(io, repositoryManager, config.Get(Settings.VendorDir));

            // load root package
            var versionParser = new BVersionParser();
            var loader        = new LoaderPackageRoot(repositoryManager, config, io, versionParser);
            var package       = loader.Load <IPackageRoot>((ConfigBucket)localBucket);

            bucket.SetPackage(package);

            // create installation manager
            var installationManager = CreateInstallationManager();

            bucket.SetInstallationManager(installationManager);

            if (fullLoad)
            {
                var downloadManager = DownloadFactory.CreateManager(io, config, transport, dispatcher);
                bucket.SetDownloadManager(downloadManager);

                // todo: initialize archive manager
            }

            // must happen after downloadManager is created since they read it out of bucket.
            InitializeDefaultInstallers(installationManager, bucket, io);

            if (fullLoad)
            {
                Bucket globalBucket = null;
                if (BaseFileSystem.GetNormalizePath(cwd) != BaseFileSystem.GetNormalizePath(config.Get(Settings.Home)))
                {
                    globalBucket = CreateGlobalBucket(io, config, disablePlugins, false);
                }

                var pluginManager = new PluginManager(io, bucket, globalBucket, disablePlugins);
                bucket.SetPluginManager(pluginManager);
                pluginManager.LoadInstalledPlugins();
            }

            // init locker if locker exists.
            if (fullLoad && !string.IsNullOrEmpty(bucketFile))
            {
                var lockFile = Path.GetExtension(bucketFile) == ".json" ?
                               bucketFile.Substring(0, bucketFile.Length - 5) + ".lock" :
                               bucketFile + ".lock";
                var locker = new Locker(
                    io,
                    new JsonFile(lockFile, localFileSystem, io), installationManager, localFileSystem.Read(bucketFile).ToText());
                bucket.SetLocker(locker);
            }

            if (fullLoad)
            {
                // Raises an event only when it is fully loaded.
                dispatcher.Dispatch(PluginEvents.Init, this);
            }

            if (fullLoad)
            {
                // once everything is initialized we can purge packages from
                // local repos if they have been deleted on the filesystem.
                PurgePackages(repositoryManager.GetLocalInstalledRepository(), installationManager);
            }

            return(bucket);
        }
Exemplo n.º 15
0
        /// <inheritdoc />
        protected override int Execute(IInput input, IOutput output)
        {
            var file       = input.GetArgument("file") ?? Factory.GetBucketFile();
            var io         = GetIO();
            var fileSystem = new FileSystemLocal();

            if (!fileSystem.Exists(file))
            {
                io.WriteError($"<error>{file} not found.</error>");
                return(ExitCodes.FileNotFoundException);
            }

            var checkPublish = !input.GetOption("no-check-publish");
            var checkLock    = !input.GetOption("no-check-lock");
            var isStrict     = input.GetOption("strict");

            var validator = new ValidatorBucket(fileSystem, io);

            var(warnings, publishErrors, errors) = validator.Validate(file);

            var lockErrors = Array.Empty <string>();
            var bucket     = Factory.Create(io, file, input.HasRawOption("--no-plugins"));
            var locker     = bucket.GetLocker();

            if (locker.IsLocked() && !locker.IsFresh())
            {
                lockErrors = new[] { "The lock file is not up to date with the latest changes in bucket.json, it is recommended that you run `bucket update`." };
            }

            OuputResult(file, ref errors, ref warnings, checkPublish, publishErrors, checkLock, lockErrors, isStrict);

            int GetStrictExitCode()
            {
                return((isStrict && !warnings.Empty()) ? ExitCodes.ValidationWarning : GameBox.Console.ExitCodes.Normal);
            }

            var exitCode = errors.Length > 0 ? ExitCodes.ValidationErrors : GetStrictExitCode();

            if (input.GetOption("with-dependencies"))
            {
                var localInstalledRepository = bucket.GetRepositoryManager().GetLocalInstalledRepository();
                foreach (var package in localInstalledRepository.GetPackages())
                {
                    var path = bucket.GetInstallationManager().GetInstalledPath(package);
                    file = Path.Combine(path, "bucket.json");

                    if (!Directory.Exists(path) || !File.Exists(file))
                    {
                        continue;
                    }

                    (warnings, publishErrors, errors) = validator.Validate(file);
                    OuputResult(file, ref errors, ref warnings, checkPublish, publishErrors, isStrict: isStrict);

                    var depCode = !errors.Empty() ? ExitCodes.ValidationErrors : GetStrictExitCode();
                    exitCode = Math.Max(depCode, exitCode);
                }
            }

            var commandEvent = new CommandEventArgs(PluginEvents.Command, "validate", input, output);

            bucket.GetEventDispatcher().Dispatch(this, commandEvent);

            return(Math.Max(exitCode, commandEvent.ExitCode));
        }
Exemplo n.º 16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ArchiverZip"/> class.
 /// </summary>
 public ArchiverZip()
 {
     fileSystem = new FileSystemLocal();
 }