Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions tools/common/lib/sqlite-integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ export abstract class SqliteIntegrationProvider {
return hasDbPhp || ! hasWpConfig;
}

async shouldKeepExistingDbDropin( sitePath: string ): Promise< boolean > {
const dbPhpPath = path.join( sitePath, 'wp-content', 'db.php' );
if ( ! fs.existsSync( dbPhpPath ) ) {
return false;
}

try {
const content = await fs.promises.readFile( dbPhpPath, 'utf8' );
return content.includes( '@studio-keep' );
} catch {
return false;
}
}

async getSqliteVersionFromInstallation( sqliteMuPluginPath: string ): Promise< string > {
try {
const versionFileContent = await fs.promises.readFile(
Expand All @@ -39,20 +53,22 @@ export abstract class SqliteIntegrationProvider {

const wpContentPath = path.join( sitePath, 'wp-content' );
const databasePath = path.join( wpContentPath, 'database' );
const sqliteSourcePath = this.getSqlitePluginSourcePath();
const sqliteDirname = this.getSqliteDirname();

await fs.promises.mkdir( databasePath, { recursive: true } );

const sqliteSourcePath = this.getSqlitePluginSourcePath();
const dbCopyContent = await fs.promises.readFile(
path.join( sqliteSourcePath, 'db.copy' ),
'utf8'
);
const sqliteDirname = this.getSqliteDirname();
const updatedContent = dbCopyContent.replace(
"'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",
`realpath( __DIR__ . '/mu-plugins/${ sqliteDirname }' )`
);
await fs.promises.writeFile( path.join( wpContentPath, 'db.php' ), updatedContent );
if ( ! ( await this.shouldKeepExistingDbDropin( sitePath ) ) ) {
const dbCopyContent = await fs.promises.readFile(
path.join( sqliteSourcePath, 'db.copy' ),
'utf8'
);
const updatedContent = dbCopyContent.replace(
"'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",
`realpath( __DIR__ . '/mu-plugins/${ sqliteDirname }' )`
);
await fs.promises.writeFile( path.join( wpContentPath, 'db.php' ), updatedContent );
}

const sqliteDestPath = path.join( wpContentPath, 'mu-plugins', sqliteDirname );
await fs.promises.rm( sqliteDestPath, { recursive: true, force: true } );
Expand Down
60 changes: 60 additions & 0 deletions tools/common/lib/tests/sqlite-integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,33 @@ platformTestSuite( 'SqliteIntegrationProvider', ( { normalize } ) => {
} );
} );

describe( 'shouldKeepExistingDbDropin', () => {
it( 'should return false when db.php does not exist', async () => {
const result = await provider.shouldKeepExistingDbDropin( MOCK_SITE_PATH );
expect( result ).toBe( false );
} );

it( 'should return false when db.php does not include the Studio keep marker', async () => {
volFromJSON( {
[ normalize( `${ MOCK_SITE_PATH }/wp-content/db.php` ) ]:
"<?php\ndefine( 'SQLITE_DB_DROPIN_VERSION', '1.8.0' );\ndefine( 'MARKDOWN_DB_DROPIN', true );",
} );

const result = await provider.shouldKeepExistingDbDropin( MOCK_SITE_PATH );
expect( result ).toBe( false );
} );

it( 'should return true when db.php includes the Studio keep marker', async () => {
volFromJSON( {
[ normalize( `${ MOCK_SITE_PATH }/wp-content/db.php` ) ]:
"<?php\n// @studio-keep\ndefine( 'SQLITE_DB_DROPIN_VERSION', '1.8.0' );\ndefine( 'MARKDOWN_DB_DROPIN', true );",
} );

const result = await provider.shouldKeepExistingDbDropin( MOCK_SITE_PATH );
expect( result ).toBe( true );
} );
} );

describe( 'installSqliteIntegration', () => {
beforeEach( () => {
volFromJSON( {
Expand All @@ -109,6 +136,39 @@ platformTestSuite( 'SqliteIntegrationProvider', ( { normalize } ) => {
);
} );

it( 'should not overwrite db.php drop-in with the Studio keep marker', async () => {
volFromJSON( {
[ normalize( `wp-files/${ SQLITE_DIRNAME }/db.copy` ) ]:
"SQLIntegration path: '{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",
[ normalize( `${ MOCK_SITE_PATH }/wp-content/db.php` ) ]:
"<?php\n// @studio-keep\ndefine( 'SQLITE_DB_DROPIN_VERSION', '1.8.0' );\ndefine( 'MARKDOWN_DB_DROPIN', true );",
} );

await provider.installSqliteIntegration( MOCK_SITE_PATH );

expect( vi.mocked( fs.promises.writeFile ) ).not.toHaveBeenCalledWith(
normalize( `${ MOCK_SITE_PATH }/wp-content/db.php` ),
expect.any( String )
);
} );

it( 'should still copy mu-plugin when db.php has the Studio keep marker', async () => {
volFromJSON( {
[ normalize( `wp-files/${ SQLITE_DIRNAME }/db.copy` ) ]:
"SQLIntegration path: '{SQLITE_IMPLEMENTATION_FOLDER_PATH}'",
[ normalize( `${ MOCK_SITE_PATH }/wp-content/db.php` ) ]:
"<?php\n// @studio-keep\ndefine( 'SQLITE_DB_DROPIN_VERSION', '1.8.0' );\ndefine( 'MARKDOWN_DB_DROPIN', true );",
} );

await provider.installSqliteIntegration( MOCK_SITE_PATH );

expect( vi.mocked( fs.promises.cp ) ).toHaveBeenCalledWith(
normalize( `wp-files/${ SQLITE_DIRNAME }` ),
normalize( `${ MOCK_SITE_PATH }/wp-content/mu-plugins/${ SQLITE_DIRNAME }` ),
expect.any( Object )
);
} );

it( 'should copy SQLite plugin to mu-plugins', async () => {
await provider.installSqliteIntegration( MOCK_SITE_PATH );

Expand Down