Пример #1
0
        public async Task <IEnumerable <IFeatureEventContext> > EnableFeatureAsync(string featureId)
        {
            // Get features to enable
            var feature = await _shellDescriptorManager.GetFeatureAsync(featureId);

            // Ensure we also enable dependencies
            var featureIds = feature.FeatureDependencies
                             .Select(d => d.ModuleId).ToArray();

            // Enable features
            return(await EnableFeaturesAsync(featureIds));
        }
Пример #2
0
        public async Task <ICommandResultBase> UpdateAsync(string moduleId)
        {
            var output = new CommandResultBase();

            // Get installed feature
            var feature = await _featureFacade.GetFeatureByIdAsync(moduleId);

            // Ensure we found the feature
            if (feature == null)
            {
                return(output.Failed(
                           $"A feature named '{moduleId}' could not be found within the ShellFeatures table."));
            }

            // Get available module
            var module = await _shellDescriptorManager.GetFeatureAsync(moduleId);

            // Ensure we found the module
            if (module == null)
            {
                return(output.Failed($"A module named '{moduleId}' could not be found on the file system. Please ensure the '{moduleId}' module exists within the root/modules folder."));
            }

            // ------------------------------------------------------------------
            // 1. Check to ensure we have a newer version of the module
            // ------------------------------------------------------------------

            var from = feature.Version.ToVersion();
            var to   = module.Descriptor.Version.ToVersion();

            if (from == null)
            {
                return(output.Failed(
                           $"Could not convert version for feature {feature.ModuleId} of {feature.Version} to a valid version. Please check the version within the shell features database table."));
            }

            if (to == null)
            {
                return(output.Failed(
                           $"Could not convert version for module {module.Descriptor.Id} of {module.Descriptor.Version} to a valid version. Please check the version within the modules manifest file."));
            }

            // No newer version simply return
            if (from >= to)
            {
                return(output.Success());
            }

            // ------------------------------------------------------------------
            // 2. Check to ensure the module we are updating is compatible
            // with the current version of Plato we are running
            // ------------------------------------------------------------------

            var modulePlatoVersion = module.Descriptor.PlatoVersion.ToVersion();

            // Does the module have a Plato version defined?
            if (modulePlatoVersion != null)
            {
                // Get current Plato version
                var currentPlatoVersion = _platoOptions.Value.Version.ToVersion();
                if (currentPlatoVersion != null)
                {
                    // Does the module require a newer version of Plato?
                    if (modulePlatoVersion > currentPlatoVersion)
                    {
                        return(output.Failed(
                                   $"{moduleId} {module.Descriptor.Version} requires Plato {modulePlatoVersion.ToString()} whilst you are running Plato {currentPlatoVersion.ToString()}. Please upgrade to Plato {modulePlatoVersion.ToString()} and try updating {moduleId} again."));
                    }
                }
            }

            // ------------------------------------------------------------------
            // 3. Invoke FeatureEventHandlers & database migrations
            // ------------------------------------------------------------------

            var results = await InvokeFeatureEventHandlersAsync(
                feature, async context =>
            {
                // The result to return
                var result = new CommandResultBase();

                // Perform migrations from current installed feature version
                // to latest available version defined via the modules IMigrationProvider

                // All versions between from and to
                var versions = from.GetVersionsBetween(to);

                // Compile versions to search
                var versionsToSearch = versions != null
                        ? versions?.ToList().Select(v => v.ToString())
                        : new List <string>();

                // Build migrations for feature & versions
                var migrations = _migrationBuilder.BuildMigrations(moduleId, versionsToSearch.ToArray());

                // Apply migrations
                var migrationResults = await migrations.ApplyMigrationsAsync();

                // We may not have migrations
                if (migrationResults != null)
                {
                    // Did any errors occur whilst applying the migration?
                    if (migrationResults.Errors.Any())
                    {
                        var errors = new List <CommandError>();
                        foreach (var error in migrationResults.Errors)
                        {
                            errors.Add(new CommandError(error.Message));
                        }

                        return(result.Failed(errors.ToArray()));
                    }
                }

                // If we reach this point everything went OK, Migrations applied
                // successfully and no errors occurred within the features update handlers.
                // Finally update the features version within the ShellFeatures table to reflect
                // the new version of the module we've just updated to, also update
                // shell descriptor to reflect version changes within dictionary store

                var updateResult = await UpdateShellFeatureVersionAsync(feature, module.Descriptor.Version);
                if (updateResult.Errors.Any())
                {
                    return(result.Failed(updateResult.Errors.ToArray()));
                }

                // Return success
                return(result.Success());
            });

            // Did any errors occur?
            var handlerErrors = results
                                .Where(c => c.Value.Errors.Any())
                                .SelectMany(h => h.Value.Errors)
                                .ToList();

            if (handlerErrors.Count > 0)
            {
                var errors = new List <CommandError>();
                foreach (var error in handlerErrors)
                {
                    errors.Add(new CommandError(error.Value));
                }
                return(output.Failed(errors.ToArray()));
            }

            // No errors, recycle shell context to apply updates
            RecycleShell();

            return(output.Success());
        }