diff --git a/CHANGELOG.md b/CHANGELOG.md index 316f0828..5af515e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ## 0.20.0 +> Released 19 May 2023 + ### Added * `New-RivetSession` function for creating a Rivet session. A `Rivet_Session` is the object used by Rivet to keep track @@ -21,6 +23,8 @@ of current state. * Shows too many errors. * `Remove-ForeignKey` prompts for `TableName` and `ReferencesTableName` arguments. +* Creating a new migration also creates an unused schema.ps1 file and writes a warning that it should be added to source +control ## 0.19.0 diff --git a/Rivet/Functions/Checkpoint-Migration.ps1 b/Rivet/Functions/Checkpoint-Migration.ps1 index 98232ff6..7792f645 100644 --- a/Rivet/Functions/Checkpoint-Migration.ps1 +++ b/Rivet/Functions/Checkpoint-Migration.ps1 @@ -46,17 +46,41 @@ function Checkpoint-Migration foreach( $databaseItem in $Session.Databases ) { - $OutputPath = Join-Path -Path $databaseItem.MigrationsRoot -ChildPath "schema.ps1" + $schemaPs1Path = Join-Path -Path $databaseItem.MigrationsRoot -ChildPath $script:schemaFileName - if ((Test-Path -Path $OutputPath) -and -not $Force) + $schemaPs1Exists = Test-Path -Path $schemaPs1Path + if (($schemaPs1Exists) -and -not $Force) { - Write-Error "Checkpoint output path ""$($OutputPath)"" already exists. Use the -Force switch to overwrite." + Write-Error "Checkpoint output path ""$($schemaPs1Path)"" already exists. Use the -Force switch to overwrite." return } - Write-Debug "Checkpoint-Migration: Exporting migration on database $($databaseItem.Name)" + $databaseName = $databaseItem.Name + Write-Debug "Checkpoint-Migration: Exporting migration on database ${databaseName}" $migration = Export-Migration -Session $Session -Database $databaseItem.Name -Checkpoint $migration = $migration -join [Environment]::NewLine - Set-Content -Path $OutputPath -Value $migration + Set-Content -Path $schemaPs1Path -Value $migration + + if (-not $schemaPs1Exists) + { + $displayPath = $schemaPs1Path | Resolve-Path -Relative + if ($displayPath -match '\.\.[\\/]') + { + $displayPath = $schemaPs1Path + } + if ($displayPath -match '\s') + { + $displayPath = """${displayPath}""" + } + + $displayName = $databaseName + if ($displayName -match '\s') + { + $displayName = """${displayName}""" + } + $msg = "Rivet created the ${displayName} database's baseline schema file ${displayPath}. Please check " + + 'this file into source control.' + Write-Information $msg -InformationAction Continue + } } } diff --git a/Rivet/Functions/Initialize-Database.ps1 b/Rivet/Functions/Initialize-Database.ps1 index be25adbe..c802cdd7 100644 --- a/Rivet/Functions/Initialize-Database.ps1 +++ b/Rivet/Functions/Initialize-Database.ps1 @@ -21,7 +21,7 @@ function Initialize-Database # Add schema.ps1 file from database's migration directory if it exists $databaseItem = $Session.CurrentDatabase - $schemaFilePath = Join-Path -Path $databaseItem.MigrationsRoot -ChildPath 'schema.ps1' + $schemaFilePath = Join-Path -Path $databaseItem.MigrationsRoot -ChildPath $script:schemaFileName if( (Test-Path -Path $schemaFilePath) ) { $migrationPaths.Add($schemaFilePath) | Out-Null diff --git a/Rivet/Functions/New-Migration.ps1 b/Rivet/Functions/New-Migration.ps1 index 546a74a5..6fc78afe 100644 --- a/Rivet/Functions/New-Migration.ps1 +++ b/Rivet/Functions/New-Migration.ps1 @@ -4,7 +4,7 @@ function New-Migration <# .SYNOPSIS Creates a new migration script. - + .DESCRIPTION Creates a migration script with a given name. The script is prefixed with the current timestamp (e.g. yyyyMMddHHmmss). The script is created in `$Path\$Database\Migrations`. #> @@ -13,7 +13,7 @@ function New-Migration [string[]] # The name of the migration to create. $Name, - + [Parameter(Mandatory=$true)] [string] # The path to the directory where the migration should be saved. @@ -41,23 +41,14 @@ function New-Migration $migrationPath = [IO.Path]::GetFullPath( $migrationPath ) New-Item -Path $migrationPath -Force -ItemType File - $schemaPs1Path = Join-Path -Path $Path -ChildPath $script:schemaFileName - if (-not (Test-Path -Path $schemaPs1Path)) - { - $script:defaultSchemaPs1Content | Set-Content -Path $schemaPs1Path - $msg = "Rivet created ""$($schemaPs1Path | Resolve-Path -Relative)"", a file where Rivet stores the " + - 'database''s baseline schema. PLEASE CHECK THIS FILE INTO SOURCE CONTROL.' - Write-Warning $msg - } - $template = @" <# -Your migration is ready to go! For the best development experience, please -write your migration in the PowerShell 3 ISE. Run the following at a +Your migration is ready to go! For the best development experience, please +write your migration in the PowerShell 3 ISE. Run the following at a PowerShell prompt: PS> ise "{0}" - + or right-click the migration in Windows Explorer and choose "Edit". The PowerShell ISE gives you intellisense, auto-complete, and other features @@ -66,7 +57,7 @@ import Rivet and get intellisense/auto-complete: PSISE> {1} -The ISE has a "Show Command" add-on which will let you build your migration +The ISE has a "Show Command" add-on which will let you build your migration with a GUI. Once you've got Rivet imported, choose View > Show Command Add-on. When the Show Command Add-on appears, choose 'Rivet' from the module. Click on a migration operation to build it with the Show Command GUI. @@ -78,7 +69,7 @@ function Push-Migration function Pop-Migration {{ }} -"@ -f $migrationPath,$importRivetPath +"@ -f $migrationPath,$importRivetPath $template | Set-Content -Path $migrationPath } diff --git a/Rivet/Rivet.psm1 b/Rivet/Rivet.psm1 index c23fc016..a1603871 100644 --- a/Rivet/Rivet.psm1 +++ b/Rivet/Rivet.psm1 @@ -40,11 +40,6 @@ class Rivet_Session [Rivet.Configuration.Database] $CurrentDatabase } -enum Rivet_QueryKeyword -{ - Default = 1 -} - $RivetSchemaName = 'rivet' $RivetMigrationsTableName = 'Migrations' $RivetMigrationsTableFullName = "[$($RivetSchemaName)].[$($RivetMigrationsTableName)]" diff --git a/Test/Checkpoint-Migration.Tests.ps1 b/Test/Checkpoint-Migration.Tests.ps1 index 75cf2c24..b8a0f904 100644 --- a/Test/Checkpoint-Migration.Tests.ps1 +++ b/Test/Checkpoint-Migration.Tests.ps1 @@ -1,3 +1,4 @@ + #Requires -Version 5.1 Set-StrictMode -Version 'Latest' @@ -121,7 +122,7 @@ BeforeAll { Migration = $schemaFileContents } $script:checkpointedMigrations.Add($checkpointedMigration) - + Remove-RivetTestDatabase -Name $databaseName # Now, check that the schema.ps1 script is runnable Invoke-RTRivet -InitializeSchema -Database $databaseName -ErrorAction Stop @@ -151,7 +152,7 @@ BeforeAll { { foreach( $path in $script:migrationPaths ) { - Set-Content -Path (Join-Path -Path $path.Directory.FullName -ChildPath 'schema.ps1') -Value $existingSchemaContents + Set-Content -Path (Join-Path -Path $path.Directory.FullName -ChildPath 'schema.ps1') -Value $existingSchemaContents } } @@ -218,7 +219,7 @@ function Pop-Migration '@ -ContainsRowsFor 'CheckpointMigration' -Database ($script:database) ThenNoErrors } - + It 'should fail when schema.ps1 file already exists' { GivenMigrationContent -Name 'CheckpointMigration' -Content @' function Push-Migration @@ -237,7 +238,7 @@ function Pop-Migration WhenCheckpointingMigration -ExistingSchemaFile -ErrorAction SilentlyContinue ThenFailed -WithError 'schema.ps1" already exists.' } - + It 'should overwrite contents when schema.ps1 file already exists but -Force switch is given' { GivenMigrationContent -Name 'CheckpointMigration' -Content @' function Push-Migration @@ -265,7 +266,7 @@ function Pop-Migration '@ -ContainsRowsFor 'CheckpointMigration' -Database $RTDatabaseName ThenNoErrors } - + It 'should pass when checkpointing a migration' { GivenMigrationContent -Name 'CheckpointMigration' -Content @' function Push-Migration @@ -289,7 +290,7 @@ function Push-Migration New-Column -DataType 'text' -Name 'textcolumn' -Description 'a text column' New-Column -DataType 'ntext' -Name 'ntextcolumn' -NotNull New-Column -DataType 'image' -Name 'imagecolumn' - New-Column -DataType 'sysname' -Name 'sysnamecolumn' -NotNull + New-Column -DataType 'sysname' -Name 'sysnamecolumn' -NotNull New-Column -DataType 'sql_variant' -Name 'sql_variantcolumn' -Sparse New-Column -DataType 'CID' -Name 'CID' -NotNull varbinary 'VarBinDefault' -Size 1 @@ -374,7 +375,7 @@ ON [dbo].[Migrations] for insert as select 1 ThenSchema -HasContent @' Add-Row -SchemaName 'rivet' -TableName 'Migrations' -Column @{ '@ -ContainsRowsFor 'CheckpointMigration' -Database $RTDatabaseName - + ThenSchema -HasContent 'Remove-Table -Name ''Migrations''' -Database $RTDatabaseName ThenSchema -Not -HasContent 'Remove-Schema' -Database $RTDatabaseName ThenSchema -Not -HasContent 'Remove-PrimaryKey' -Database $RTDatabaseName @@ -385,7 +386,7 @@ ON [dbo].[Migrations] for insert as select 1 ThenSchema -Not -HasContent 'Remove-Trigger' -Database $RTDatabaseName ThenNoErrors } - + It 'should only checkpoint pushed migrations when there are multiple migrations but only one has been pushed' { GivenMigrationContent -Name 'CheckpointMigration' -Content @' function Push-Migration @@ -477,7 +478,7 @@ function Pop-Migration '@ -ContainsRowsFor 'CheckpointMigration', 'CheckpointMigration2' -Database $RTDatabaseName ThenNoErrors } - + It 'should do nothing when no migrations have been pushed' { # Nothing to push here. Just running push here to initialize database with rivet.migrations table. Invoke-RTRivet -Push -Database $RTDatabaseName diff --git a/Test/RivetTest/RivetTest.psm1 b/Test/RivetTest/RivetTest.psm1 index 216a8682..48150d34 100644 --- a/Test/RivetTest/RivetTest.psm1 +++ b/Test/RivetTest/RivetTest.psm1 @@ -1,4 +1,6 @@ +using module '..\..\Rivet' + param( [String]$RivetRoot )