< Summary - Jellyfin

Information
Class: Jellyfin.Server.Migrations.Stages.CodeMigration
Assembly: jellyfin
File(s): /srv/git/jellyfin/Jellyfin.Server/Migrations/Stages/CodeMigration.cs
Line coverage
93%
Covered lines: 14
Uncovered lines: 1
Coverable lines: 15
Total lines: 64
Line coverage: 93.3%
Branch coverage
50%
Covered branches: 3
Total branches: 6
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 5/16/2026 - 12:15:55 AM Line coverage: 62.9% (17/27) Branch coverage: 57.1% (8/14) Total lines: 8710/29/2026 - 12:17:11 AM Line coverage: 93.3% (14/15) Branch coverage: 50% (3/6) Total lines: 64 5/16/2026 - 12:15:55 AM Line coverage: 62.9% (17/27) Branch coverage: 57.1% (8/14) Total lines: 8710/29/2026 - 12:17:11 AM Line coverage: 93.3% (14/15) Branch coverage: 50% (3/6) Total lines: 64

Coverage delta

Coverage delta 31 -31

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
BuildCodeMigrationId()100%11100%
Perform()50%2287.5%
IsMigrationRoutine(...)50%22100%
RunAsync()50%2280%

File(s)

/srv/git/jellyfin/Jellyfin.Server/Migrations/Stages/CodeMigration.cs

#LineLine coverage
 1using System;
 2using System.Globalization;
 3using System.Threading;
 4using System.Threading.Tasks;
 5using Jellyfin.Server.ServerSetupApp;
 6using Microsoft.Extensions.DependencyInjection;
 7
 8namespace Jellyfin.Server.Migrations.Stages;
 9
 10internal class CodeMigration(Type migrationType, JellyfinMigrationAttribute metadata, JellyfinMigrationBackupAttribute? 
 11{
 12    public Type MigrationType { get; } = migrationType;
 13
 14    public JellyfinMigrationAttribute Metadata { get; } = metadata;
 15
 16    public JellyfinMigrationBackupAttribute? BackupRequirements { get; set; } = migrationBackupAttribute;
 17
 18    public string BuildCodeMigrationId()
 19    {
 63072720        return Metadata.Order.ToString("yyyyMMddHHmmsss", CultureInfo.InvariantCulture) + "_" + Metadata.Name!;
 21    }
 22
 23    public async Task Perform(IServiceProvider serviceProvider, IStartupLogger logger, CancellationToken cancellationTok
 24    {
 13725        if (!IsMigrationRoutine(MigrationType))
 26        {
 027            throw new InvalidOperationException($"The type {MigrationType} does not implement either IMigrationRoutine o
 28        }
 29
 30        // The routine runs against a scope of the applications own container. Copying the application service
 31        // descriptors into a child container instead would make that child container the owner of every singleton it
 32        // forwards, so disposing it after the migration would also dispose the applications own instance of services
 33        // like the ProviderManager and leave the server broken until the next restart.
 13734        var scope = serviceProvider.CreateAsyncScope();
 13735        await using (scope.ConfigureAwait(false))
 36        {
 37            // Nests everything the routine logs through an injected IStartupLogger under the migrations own topic.
 13738            using (StartupLogger.BeginAmbientTopic(logger.Topic))
 39            {
 13740                await RunAsync(ActivatorUtilities.CreateInstance(scope.ServiceProvider, MigrationType), cancellationToke
 13741            }
 42        }
 13743    }
 44
 45    // The obsolete IMigrationRoutine is still implemented by every routine that predates the async interface, so
 46    // the members that have to touch it are grouped here behind a single suppression.
 47#pragma warning disable CS0618 // Type or member is obsolete
 48    private static bool IsMigrationRoutine(Type migrationType)
 49    {
 13750        return typeof(IMigrationRoutine).IsAssignableFrom(migrationType) || typeof(IAsyncMigrationRoutine).IsAssignableF
 51    }
 52
 53    private static async Task RunAsync(object routine, CancellationToken cancellationToken)
 54    {
 13755        if (routine is IMigrationRoutine migrationRoutine)
 56        {
 13557            migrationRoutine.Perform();
 13558            return;
 59        }
 60
 261        await ((IAsyncMigrationRoutine)routine).PerformAsync(cancellationToken).ConfigureAwait(false);
 13762    }
 63#pragma warning restore CS0618 // Type or member is obsolete
 64}