Skip to content

Commit

Permalink
[feat] Added revert field and restore all .env file from json system
Browse files Browse the repository at this point in the history
  • Loading branch information
erdemkosk committed Nov 14, 2023
1 parent acc7b33 commit f07f969
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 8 deletions.
20 changes: 16 additions & 4 deletions bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
compareEnvFiles,
syncEnvFile,
promptForEnvVariable,
getUniqueEnvNames
getUniqueEnvNames,
restoreEnvFile
} from '../lib/env-operations'

import {
Expand Down Expand Up @@ -169,7 +170,7 @@ program

program
.command('update')
.description('UPDATE a single field in .env file and create a version')
.description(`${chalk.yellow('UPDATE')} a single field in .env file and create a version.`)
.alias('u')
.action(async () => {
const files = await getEnvFilesRecursively({ directory: getBaseFolder() })
Expand Down Expand Up @@ -212,8 +213,8 @@ program
})

program
.command('restore')
.description('Restore a field in .env file to a specific version')
.command('revert')
.description(`${chalk.yellow('REVERT')} a field in .env file to a specific version`)
.alias('r')
.action(async () => {
const files = await getEnvFilesRecursively({ directory: getBaseFolder() })
Expand Down Expand Up @@ -266,4 +267,15 @@ program
}
})

program
.command('restore-env')
.description(`${chalk.yellow('RESTORE')} the .env file based on the latest changes in the version.json file.`)
.action(async () => {
const isSuccess = await restoreEnvFile()

isSuccess
? console.log('Reversion was successful. You are ready to go!')
: console.log('There was a problem reverting .env file.')
})

program.parse(process.argv)
58 changes: 55 additions & 3 deletions lib/env-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
} from './file-operations'

import {
saveFieldVersion
saveFieldVersion,
saveFieldVersionsInSync
} from './history-operations'

function getServiceNameFromUrl ({ targetPath }: { targetPath: string }): string {
Expand Down Expand Up @@ -240,11 +241,13 @@ async function syncEnvFile (): Promise<boolean> {
return false
}

await createFolderIfDoesNotExist(serviceFolderPath)
const envValues = await getValuesInEnv({ targetPath: path.join(currentDirectory, '.env') })

await createFolderIfDoesNotExist(serviceFolderPath)
await copyFile(path.join(currentDirectory, '.env'), path.join(serviceFolderPath, '.env'))
await deleteFile(path.join(currentDirectory, '.env'))
await createSymlink({ targetPath: path.join(serviceFolderPath, '.env') })
await saveFieldVersionsInSync(serviceFolderPath, envValues.data)

return true
}
Expand Down Expand Up @@ -310,6 +313,54 @@ async function getEnvValue (targetFolder: string, envName: string): Promise<stri
return undefined
}

async function restoreEnvFile (): Promise<boolean> {
const currentDirectory = process.cwd()
const directoryName = currentDirectory.split('/').pop() ?? ''
const serviceFolderPath = path.join(getBaseFolder(), directoryName)
const versionFilePath = path.join(serviceFolderPath, 'version.json')

const versionFileContent = await readFile({ file: versionFilePath })

if (versionFileContent === undefined) {
console.error('Version file content is undefined.')
return false
}

const versions = JSON.parse(versionFileContent)

if (!Array.isArray(versions)) {
console.error('Versions is not an array.')
return false
}

const latestValues: Record<string, string> = {}

for (let i = 0; i < versions.length; i++) {
const changes = versions[i]?.changes

// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (!changes || changes.length === 0) {
continue
}

for (const change of changes) {
latestValues[change.fieldName] = change.value
}
}

const newEnvContent = Object.entries(latestValues)
.map(([fieldName, value]) => `${fieldName}=${value}`)
.join('\n')

const newEnvFilePath = path.join(serviceFolderPath, '.env')

await writeFile({ file: newEnvFilePath, newFileContents: newEnvContent })

await createSymlink({ targetPath: newEnvFilePath })

return true
}

export {
createEnvFile,
updateEnvFile,
Expand All @@ -322,5 +373,6 @@ export {
getServiceNameFromUrl,
splitEnvLine,
getUniqueEnvNames,
getEnvValue
getEnvValue,
restoreEnvFile
}
36 changes: 36 additions & 0 deletions lib/history-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,42 @@ export async function saveFieldVersion (targetPath: string, fieldName: string, v
}
}

export async function saveFieldVersionsInSync (serviceFolderPath: string, envValues: string[][] | undefined): Promise<void> {
if (envValues === undefined) {
console.error('Env values are undefined.')
return
}

const versionFilePath = path.join(serviceFolderPath, 'version.json')
await createFileIfNotExists(versionFilePath)

const versionFileContent = await readFile({ file: versionFilePath })

let versions = versionFileContent !== undefined ? JSON.parse(versionFileContent) : []

if (!Array.isArray(versions)) {
versions = []
}

for (const [fieldName, value] of envValues) {
const oldValue = await getEnvValue(path.join(serviceFolderPath, '.env'), fieldName)

console.log(oldValue)

const newVersion = {
timestamp: new Date().toISOString(),
changes: [{ fieldName, oldValue, value }]
}

versions.push(newVersion)
}

await writeFile({
file: versionFilePath,
newFileContents: JSON.stringify(versions, null, 2)
})
}

export async function getEnvVersions (targetPath: string, fieldName: string): Promise<IEnvVersion[]> {
const versionFilePath = path.join(path.dirname(targetPath), 'version.json')
const versionFileContent = await readFile({ file: versionFilePath })
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "envolve",
"version": "1.0.9",
"version": "1.1.0",
"description": "Envolve CLI is a powerful tool for managing environment variables in your projects. It allows you to easily create, update, compare, and sync environment files across different services.",
"main": "index.ts",
"scripts": {
Expand Down

0 comments on commit f07f969

Please sign in to comment.