Skip to content

Commit

Permalink
Merge branch 'trunk' into update/refresh-available-nodejs-versions
Browse files Browse the repository at this point in the history
  • Loading branch information
iamchughmayank authored Nov 11, 2024
2 parents cb0ca94 + 1bd87c2 commit 74f01e9
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 29 deletions.
11 changes: 8 additions & 3 deletions __tests__/commands/dev-env-sync-sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ describe( 'commands/DevEnvSyncSQLCommand', () => {
blogId: 2,
homeUrl: 'https://subsite.com',
},
{
blogId: 3,
homeUrl: 'https://another.com/path',
},
],
},
};
Expand All @@ -56,7 +60,7 @@ describe( 'commands/DevEnvSyncSQLCommand', () => {
it( 'should return a map of search-replace values', () => {
const cmd = new DevEnvSyncSQLCommand( app, env, 'test-slug', lando );
cmd.slug = 'test-slug';
cmd.siteUrls = [ 'test.go-vip.com' ];
cmd.siteUrls = [ 'http://test.go-vip.com' ];
cmd.generateSearchReplaceMap();

expect( cmd.searchReplaceMap ).toEqual( { 'test.go-vip.com': 'test-slug.vipdev.lndo.site' } );
Expand All @@ -65,12 +69,13 @@ describe( 'commands/DevEnvSyncSQLCommand', () => {
it( 'should return a map of search-replace values for multisite', () => {
const cmd = new DevEnvSyncSQLCommand( app, msEnv, 'test-slug', lando );
cmd.slug = 'test-slug';
cmd.siteUrls = [ 'test.go-vip.com', 'subsite.com' ];
cmd.siteUrls = [ 'https://test.go-vip.com', 'http://subsite.com', 'http://another.com/path' ];
cmd.generateSearchReplaceMap();

expect( cmd.searchReplaceMap ).toEqual( {
'test.go-vip.com': 'test-slug.vipdev.lndo.site',
'subsite.com': 'subsite-com-2.test-slug.vipdev.lndo.site',
'subsite.com': 'subsite-com.test-slug.vipdev.lndo.site',
'another.com/path': 'another-com.test-slug.vipdev.lndo.site/path',
} );
} );
} );
Expand Down
14 changes: 7 additions & 7 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
"dockerode": "^4.0.0",
"eslint": "^8.35.0",
"jest": "^29.7.0",
"nock": "13.5.5",
"nock": "13.5.6",
"prettier": "npm:[email protected]",
"rimraf": "6.0.1",
"typescript": "^5.2.2"
Expand Down
2 changes: 1 addition & 1 deletion src/commands/dev-env-import-sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class DevEnvImportSQLCommand {
* Therefore, for the things to work, we have to pretend that stdin is not a TTY :-)
*/
process.stdin.isTTY = false;
await exec( lando, this.slug, importArg, { stdio: [ fd, 'pipe', 'pipe' ] } );
await exec( lando, this.slug, importArg, { stdio: [ fd.fd, 'pipe', 'pipe' ] } );

if ( ! this.options.quiet ) {
console.log( `${ chalk.green.bold( 'Success:' ) } Database imported.` );
Expand Down
91 changes: 76 additions & 15 deletions src/commands/dev-env-sync-sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import chalk from 'chalk';
import fs from 'fs';
import Lando from 'lando';
import { pipeline } from 'node:stream/promises';
import urlLib from 'url';

import { DevEnvImportSQLCommand, DevEnvImportSQLOptions } from './dev-env-import-sql';
import { ExportSQLCommand } from './export-sql';
Expand All @@ -18,6 +17,27 @@ import { fixMyDumperTransform, getSqlDumpDetails, SqlDumpType } from '../lib/dat
import { makeTempDir } from '../lib/utils';
import { getReadInterface } from '../lib/validations/line-by-line';

/**
* Replaces the domain in the given URL
*
* @param string str The URL to replace the domain in.
* @param string domain The new domain
* @return The URL with the new domain
*/
const replaceDomain = ( str: string, domain: string ): string =>
str.replace( /^([^:]+:\/\/)([^:/]+)/, `$1${ domain }` );

/**
* Strips the protocol from the URL
*
* @param string url The URL to strip the protocol from
* @return The URL without the protocol
*/
function stripProtocol( url: string ): string {
const parts = url.split( '//', 2 );
return parts.length > 1 ? parts[ 1 ] : parts[ 0 ];
}

/**
* Finds the site home url from the SQL line
*
Expand All @@ -27,8 +47,12 @@ import { getReadInterface } from '../lib/validations/line-by-line';
function findSiteHomeUrl( sql: string ): string | null {
const regex = `['"](siteurl|home)['"],\\s?['"](.*?)['"]`;
const url = sql.match( regex )?.[ 2 ] || '';

return urlLib.parse( url ).hostname || null;
try {
new URL( url );
return url;
} catch {
return null;
}
}

/**
Expand All @@ -42,17 +66,17 @@ async function extractSiteUrls( sqlFile: string ): Promise< string[] > {
const readInterface = await getReadInterface( sqlFile );

return new Promise( ( resolve, reject ) => {
const domains: Set< string > = new Set();
const urls: Set< string > = new Set();
readInterface.on( 'line', line => {
const domain = findSiteHomeUrl( line );
if ( domain ) {
domains.add( domain );
const url = findSiteHomeUrl( line );
if ( url ) {
urls.add( url );
}
} );

readInterface.on( 'close', () => {
// Soring by length so that longest domains are replaced first
resolve( Array.from( domains ).sort( ( dom1, dom2 ) => dom2.length - dom1.length ) );
// Soring by length so that longest URLs are replaced first
resolve( Array.from( urls ).sort( ( url1, url2 ) => url2.length - url1.length ) );
} );

readInterface.on( 'error', reject );
Expand Down Expand Up @@ -168,7 +192,9 @@ export class DevEnvSyncSQLCommand {
this.searchReplaceMap = {};

for ( const url of this.siteUrls ) {
this.searchReplaceMap[ url ] = this.landoDomain;
this.searchReplaceMap[ stripProtocol( url ) ] = stripProtocol(
replaceDomain( url, this.landoDomain )
);
}

const networkSites = this.env.wpSitesSDS?.nodes;
Expand All @@ -177,12 +203,18 @@ export class DevEnvSyncSQLCommand {
for ( const site of networkSites ) {
if ( ! site?.blogId || site.blogId === 1 ) continue;

const url = site?.homeUrl?.replace( /https?:\/\//, '' );
if ( ! url || ! this.searchReplaceMap[ url ] ) continue;
const url = site?.homeUrl;
if ( ! url ) continue;

const strippedUrl = stripProtocol( url );
if ( ! this.searchReplaceMap[ strippedUrl ] ) continue;

const domain = new URL( url ).hostname;
const newDomain = `${ this.slugifyDomain( domain ) }.${ this.landoDomain }`;

this.searchReplaceMap[ url ] = `${ this.slugifyDomain( url ) }-${ site.blogId }.${
this.landoDomain
}`;
this.searchReplaceMap[ stripProtocol( url ) ] = stripProtocol(
replaceDomain( url, newDomain )
);
}
}

Expand Down Expand Up @@ -213,6 +245,34 @@ export class DevEnvSyncSQLCommand {
await importCommand.run();
}

public async fixBlogsTable(): Promise< void > {
const networkSites = this.env.wpSitesSDS?.nodes;
if ( ! networkSites ) {
return;
}

const queries: string[] = [];
for ( const site of networkSites ) {
if ( ! site?.blogId || ! site?.homeUrl ) {
continue;
}

const oldDomain = new URL( site.homeUrl ).hostname;
const newDomain =
site.blogId !== 1
? `${ this.slugifyDomain( oldDomain ) }.${ this.landoDomain }`
: this.landoDomain;

queries.push(
`UPDATE wp_blogs SET domain = '${ newDomain }' WHERE blog_id = ${ Number( site.blogId ) };`
);
}

if ( queries.length ) {
await fs.promises.appendFile( this.sqlFile, queries.join( '\n' ) );
}
}

/**
* Sequentially runs the commands to export, search-replace, and import the SQL file
* to the local environment
Expand Down Expand Up @@ -273,6 +333,7 @@ export class DevEnvSyncSQLCommand {
}

await this.runSearchReplace();
await this.fixBlogsTable();
console.log( `${ chalk.green( '✓' ) } Search-replace operation is complete` );
} catch ( err ) {
const error = err as Error;
Expand Down
5 changes: 3 additions & 2 deletions src/lib/dev-environment/dev-environment-lando.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Lando, { type LandoConfig } from 'lando/lib/lando';
import landoUtils, { type AppInfo } from 'lando/plugins/lando-core/lib/utils';
import landoBuildTask from 'lando/plugins/lando-tooling/lib/build';
import { lookup } from 'node:dns/promises';
import { FileHandle, mkdir, rename } from 'node:fs/promises';
import { mkdir, rename } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import path, { dirname } from 'node:path';
import { satisfies } from 'semver';
Expand All @@ -24,9 +24,10 @@ import UserError from '../user-error';

import type { NetworkInspectInfo } from 'dockerode';
import type Landerode from 'lando/lib/docker';
import type { StdioOptions } from 'node:child_process';

export interface LandoExecOptions {
stdio?: string | [ FileHandle, string, string ];
stdio?: StdioOptions;
}

/**
Expand Down

0 comments on commit 74f01e9

Please sign in to comment.