-
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[pkg/velox-luna]: Implement smart diff (#56)
- Loading branch information
Showing
12 changed files
with
334 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@inox-tools/velox-luna": minor | ||
--- | ||
|
||
Implement auto-diff with renames |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<p align="center"> | ||
<img alt="InoxTools" width="350px" src="https://github.com/Fryuni/inox-tools/blob/main/assets/shield.png?raw=true"/> | ||
</p> | ||
|
||
# Velox Luna | ||
|
||
Workflow automation for [Lunaria](https://lunaria.dev/). | ||
|
||
### License | ||
|
||
Velox Luna is available under the MIT license. |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { parseArgs } from 'node:util'; | ||
|
||
export function parseCommand() { | ||
const { | ||
positionals: [locale, targetFile, other], | ||
values: { config: configPath, rebuild = false }, | ||
} = parseArgs({ | ||
options: { | ||
config: { | ||
type: 'string', | ||
multiple: false, | ||
short: 'c', | ||
default: './lunaria.config.json', | ||
}, | ||
rebuild: { | ||
type: 'boolean', | ||
multiple: false, | ||
short: 'r', | ||
default: false, | ||
}, | ||
}, | ||
allowPositionals: true, | ||
strict: true, | ||
}); | ||
|
||
if (locale === undefined) { | ||
throw new Error('Missing locale argument'); | ||
} | ||
|
||
if (targetFile === undefined) { | ||
throw new Error('Missing targetFile argument'); | ||
} | ||
|
||
if (other !== undefined) { | ||
throw new Error('Unexpected argument: ' + other); | ||
} | ||
|
||
if (!configPath) { | ||
throw new Error('Missing config argument.'); | ||
} | ||
|
||
return { locale, targetFile, configPath, rebuild }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { git } from '@lunariajs/core/git'; | ||
import { spawn } from 'node:child_process'; | ||
|
||
export async function getAllFileRenames( | ||
currentPath: string, | ||
sinceCommit: string | ||
): Promise<string[]> { | ||
const res = await git.raw([ | ||
'log', | ||
'--name-status', | ||
'--diff-filter=R', | ||
'--pretty=format:', | ||
`${sinceCommit}...HEAD`, | ||
]); | ||
|
||
const fileRenames = res | ||
.trim() | ||
.split('\n') | ||
.filter((line) => line.charAt(0) === 'R') | ||
.map((line) => line.split('\t')) | ||
.map(([, from, to]) => ({ from, to })); | ||
|
||
let latestName = currentPath; | ||
const previousNames: string[] = []; | ||
|
||
for (const { from, to } of fileRenames) { | ||
if (latestName === to) { | ||
previousNames.push(from); | ||
latestName = from; | ||
} | ||
} | ||
|
||
return previousNames; | ||
} | ||
|
||
export async function showDiffForFile(filePath: string, sinceCommit: string): Promise<void> { | ||
const oldNames = await getAllFileRenames(filePath, sinceCommit); | ||
|
||
await new Promise<void>((resolve, reject) => { | ||
const cmd = spawn( | ||
'git', | ||
['diff', '--find-renames', `${sinceCommit}...HEAD`, '--', filePath, ...oldNames], | ||
{ | ||
stdio: 'inherit', | ||
} | ||
); | ||
|
||
cmd.once('close', (code) => { | ||
if (code === 0) { | ||
resolve(); | ||
} else { | ||
reject(new Error(`git diff exited with code ${code}`)); | ||
} | ||
}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { parseCommand } from './command.js'; | ||
import { showDiffForFile } from './diff.js'; | ||
import { getCommitRange, getTargetStatus } from './status.js'; | ||
|
||
async function main() { | ||
const command = parseCommand(); | ||
|
||
const targetStatus = await getTargetStatus(command); | ||
const commitRange = await getCommitRange(targetStatus); | ||
|
||
await showDiffForFile(targetStatus.sourceFile, commitRange.from); | ||
|
||
/* | ||
BRANCH_SLUG="i18n/$(echo "$TARGET_FILE" | iconv -t ascii//TRANSLIT | sed -r s/[^a-zA-Z0-9]+/-/g | sed -r s/^-+\|-+$//g | tr A-Z a-z)" | ||
echo "Branch slug: $BRANCH_SLUG" | ||
git checkout main || true | ||
git branch -D "$BRANCH_SLUG" || true | ||
git checkout -b "$BRANCH_SLUG" main | ||
git diff --find-renames "$LATEST_TRANSLATED_COMMIT...HEAD" -- "$ORIGINAL_FILE" | ||
git add "$TRANSLATED_FILE" | ||
git commit -m "i18n($TARGET_LANGUAGE): Update \`$TARGET_FILE\`" -- "$TRANSLATED_FILE" | ||
git push --set-upstream origin "$BRANCH_SLUG" | ||
*/ | ||
} | ||
|
||
process.setSourceMapsEnabled(true); | ||
|
||
main().catch((error) => { | ||
// eslint-disable-next-line no-console | ||
console.error(error); | ||
|
||
process.exit(1); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { loadConfig, type LunariaConfig } from '@lunariajs/core/config'; | ||
import { git } from '@lunariajs/core/git'; | ||
import { lunaria, type LocalizationStatus, type GitHistory } from '@lunariajs/core'; | ||
import { join } from 'node:path'; | ||
import { readFile, writeFile, mkdir } from 'node:fs/promises'; | ||
import type { parseCommand } from './command.js'; | ||
|
||
type CommitRange = { | ||
from: string; | ||
to: string; | ||
}; | ||
|
||
export async function getCommitRange(target: TargetStatus): Promise<CommitRange> { | ||
const latestTranslatedCommit = await getCommitHashFromInfo(target); | ||
|
||
const from = latestTranslatedCommit; | ||
const to = 'HEAD'; | ||
|
||
return { from, to }; | ||
} | ||
|
||
async function getCommitHashFromInfo(target: TargetStatus): Promise<string> { | ||
if (!!target.git.lastMajorCommitHash) return target.git.lastMajorCommitHash; | ||
|
||
const res = await git.raw([ | ||
'git', | ||
'log', | ||
'--follow', | ||
'--format=%H', | ||
`--since="${target.git.lastMajorChange}"`, | ||
'--', | ||
target.localizedFile, | ||
]); | ||
|
||
return res.trim().split('\n').at(-1)!.trim(); | ||
} | ||
|
||
type TargetStatus = { | ||
sourceFile: string; | ||
localizedFile: string; | ||
git: GitHistory; | ||
}; | ||
|
||
export async function getTargetStatus( | ||
command: ReturnType<typeof parseCommand> | ||
): Promise<TargetStatus> { | ||
const { userConfig } = await loadConfig(command.configPath); | ||
|
||
const status = await getStatus(userConfig, command.rebuild); | ||
|
||
const targetFileStatus = status.find((s) => s.sharedPath.endsWith(command.targetFile)); | ||
|
||
if (targetFileStatus === undefined) { | ||
throw new Error(`Could not find status for target file: ${command.targetFile}`); | ||
} | ||
|
||
const localizedStatus = targetFileStatus.localizations[command.locale]; | ||
|
||
if (localizedStatus === undefined || localizedStatus.isMissing) { | ||
throw new Error(`Could not find localization for locale: ${command.locale}`); | ||
} | ||
|
||
return { | ||
sourceFile: targetFileStatus.sourceFile.path, | ||
localizedFile: localizedStatus.path, | ||
git: localizedStatus.git, | ||
}; | ||
} | ||
|
||
async function getStatus(config: LunariaConfig, rebuild: boolean): Promise<LocalizationStatus[]> { | ||
const statusPath = join(config.outDir, 'status.json'); | ||
|
||
if (!rebuild) { | ||
const prebuiltContent = await readFile(statusPath, 'utf-8').catch(() => null); | ||
|
||
if (prebuiltContent !== null) { | ||
return JSON.parse(prebuiltContent); | ||
} | ||
} | ||
|
||
const newProcessedStatus = await lunaria(config); | ||
|
||
// Ensure output directory exists | ||
await mkdir(config.outDir, { recursive: true }); | ||
await writeFile(statusPath, JSON.stringify(newProcessedStatus, null, 2)); | ||
|
||
return newProcessedStatus; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { defineConfig } from 'tsup'; | ||
|
||
export default defineConfig({ | ||
entry: ['src/index.ts'], | ||
format: ['cjs'], | ||
target: 'node18', | ||
banner: { js: '#!/usr/bin/env node' }, | ||
bundle: true, | ||
sourcemap: true, | ||
clean: true, | ||
splitting: true, | ||
minify: false, | ||
external: [], | ||
noExternal: ['@lunariajs/core'], | ||
treeshake: 'smallest', | ||
tsconfig: 'tsconfig.json', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
diff --git a/dist/shared/core.1a197e9d.d.mts b/dist/shared/core.1a197e9d.d.mts | ||
index e82d99d71e00d1f611ee2ee690de6ac572dbac39..c41b68b8b2f3aac0cf1ff9a162f3af2797cb7b49 100644 | ||
--- a/dist/shared/core.1a197e9d.d.mts | ||
+++ b/dist/shared/core.1a197e9d.d.mts | ||
@@ -602,8 +602,10 @@ type LunariaUserRendererConfig = z.input<typeof LunariaRendererConfigSchema>; | ||
type GitHistory = { | ||
lastChange: string; | ||
lastCommitMessage: string; | ||
+ lastCommitHash?: string; | ||
lastMajorChange: string; | ||
lastMajorCommitMessage: string; | ||
+ lastMajorCommitHash?: string; | ||
}; | ||
type GitHosting = { | ||
gitHostingFileURL: string; | ||
diff --git a/dist/status/index.mjs b/dist/status/index.mjs | ||
index 828072dae0523cb49bbe72464a866b397923f67b..02e5e7d75bdf529a47a3787c908c4ccd52fa6671 100644 | ||
--- a/dist/status/index.mjs | ||
+++ b/dist/status/index.mjs | ||
@@ -268,8 +268,10 @@ async function getFileData(filePath, isSourceLocale, isShallowRepo, rootDir, loc | ||
git: { | ||
lastChange: toUtcString(lastCommit.date), | ||
lastCommitMessage: lastCommit.message, | ||
+ lastCommirHash: lastCommit.hash, | ||
lastMajorChange: toUtcString(lastMajorCommit.date), | ||
- lastMajorCommitMessage: lastMajorCommit.message | ||
+ lastMajorCommitMessage: lastMajorCommit.message, | ||
+ lastMajorCommitHash: lastMajorCommit.hash | ||
} | ||
}; | ||
} |
Oops, something went wrong.