Skip to content

Commit

Permalink
Add support for python upgrade rules
Browse files Browse the repository at this point in the history
  • Loading branch information
thsparks committed Nov 9, 2023
1 parent 3ea61b6 commit a2e4ee1
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 8 deletions.
1 change: 1 addition & 0 deletions localtypings/pxtarget.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,7 @@ declare namespace ts.pxtc {
flashChecksumAddr?: number;
ramSize?: number;
patches?: pxt.Map<UpgradePolicy[]>; // semver range -> upgrade policies
pyPatches?: pxt.Map<UpgradePolicy[]>; // semver range -> upgrade policies
openocdScript?: string;
uf2Family?: string;
onStartText?: boolean;
Expand Down
25 changes: 18 additions & 7 deletions pxtcompiler/simpledriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ namespace pxt {
return mainPkg.getCompileOptionsAsync(target)
}).then(opts => {
patchTS(mainPkg.targetVersion(), opts)
if (mainPkg.getPreferredEditor() === pxt.PYTHON_PROJECT_NAME) {
patchPY(mainPkg.targetVersion(), opts)
}
prepPythonOptions(opts)
return opts
})
Expand All @@ -194,16 +197,24 @@ namespace pxt {
}

export function patchTS(version: string, opts: pxtc.CompileOptions) {
patchText(version, opts, ".ts");
}

export function patchPY(version: string, opts: pxtc.CompileOptions) {
patchText(version, opts, ".py");
}

export function patchText(version: string, opts: pxtc.CompileOptions, extension: string) {
if (!version)
return
pxt.debug(`applying TS patches relative to ${version}`)
pxt.debug(`applying ${extension.replace('.', '')} patches relative to ${version}`)
for (let fn of Object.keys(opts.fileSystem)) {
if (fn.indexOf("/") == -1 && U.endsWith(fn, ".ts")) {
const ts = opts.fileSystem[fn]
const ts2 = pxt.patching.patchJavaScript(version, ts)
if (ts != ts2) {
pxt.debug(`applying TS patch to ${fn}`)
opts.fileSystem[fn] = ts2
if (fn.indexOf("/") == -1 && U.endsWith(fn, extension)) {
const initial = opts.fileSystem[fn]
const patched = pxt.patching.patchPython(version, initial)
if (initial != patched) {
pxt.debug(`applying ${extension.replace('.', '')} patch to ${fn}`)
opts.fileSystem[fn] = patched
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions pxtlib/patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ namespace pxt.patching {
export function computePatches(version: string, kind?: string): ts.pxtc.UpgradePolicy[] {
const patches = pxt.appTarget.compile ? pxt.appTarget.compile.patches : undefined;
if (!patches) return undefined;
return parsePatches(version, patches, kind);
}

export function computePyPatches(version: string, kind?: string): ts.pxtc.UpgradePolicy[] {
const patches = pxt.appTarget.compile ? pxt.appTarget.compile.pyPatches : undefined;
if (!patches) return undefined;
return parsePatches(version, patches, kind);
}

function parsePatches(version: string, patches: Map<ts.pxtc.UpgradePolicy[]>, kind?: string): ts.pxtc.UpgradePolicy[] {
const v = pxt.semver.tryParse(version || "0.0.0") || pxt.semver.tryParse("0.0.0");
let r: ts.pxtc.UpgradePolicy[] = [];
Object.keys(patches)
Expand Down Expand Up @@ -30,6 +40,15 @@ namespace pxt.patching {

export function patchJavaScript(pkgTargetVersion: string, fileContents: string): string {
const upgrades = pxt.patching.computePatches(pkgTargetVersion);
return patchTextCode(pkgTargetVersion, fileContents, upgrades);
}

export function patchPython(pkgTargetVersion: string, fileContents: string): string {
const upgrades = pxt.patching.computePyPatches(pkgTargetVersion);
return patchTextCode(pkgTargetVersion, fileContents, upgrades);
}

function patchTextCode(pkgTargetVersion: string, fileContents: string, upgrades: pxtc.UpgradePolicy[]): string {
let updatedContents = fileContents;
if (upgrades) {
upgrades.filter(u => u.type === "api").forEach(rule => {
Expand Down
42 changes: 41 additions & 1 deletion webapp/src/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,12 @@ export function applyUpgradesAsync(): Promise<UpgradeResult> {
});
}

const upgradeOp = epkg.header.editor !== pxt.BLOCKS_PROJECT_NAME ? upgradeFromTSAsync : upgradeFromBlocksAsync;
const upgradeOp =
epkg.header.editor !== pxt.BLOCKS_PROJECT_NAME
? epkg.header.editor !== pxt.PYTHON_PROJECT_NAME
? upgradeFromTSAsync
: upgradeFromPythonAsync
: upgradeFromBlocksAsync;

let projectNeverCompiled = false;

Expand Down Expand Up @@ -953,6 +958,37 @@ function upgradeFromTSAsync(): Promise<UpgradeResult> {
});
}

function upgradeFromPythonAsync(): Promise<UpgradeResult> {
const mainPkg = pkg.mainPkg;
const project = pkg.getEditorPkg(mainPkg);
const targetVersion = project.header.targetVersion;

const patchedFiles: pxt.Map<string> = {};
pxt.Util.values(project.files).filter(isPyFile).forEach(file => {
const patched = pxt.patching.patchPython(targetVersion, file.content);
if (patched != file.content) {
patchedFiles[file.name] = patched;
}
});

pxt.debug("Applying upgrades to Python")

return checkPatchAsync(patchedFiles)
.then(() => {
return {
success: true,
editor: pxt.PYTHON_PROJECT_NAME,
patchedFiles
};
})
.catch(e => {
return {
success: false,
errorCodes: e.errorCodes
};
});
}

interface UpgradeError extends Error {
errorCodes?: pxt.Map<number>;
}
Expand Down Expand Up @@ -1000,6 +1036,10 @@ function isTsFile(file: pkg.File) {
return pxt.Util.endsWith(file.getName(), ".ts");
}

function isPyFile(file: pkg.File) {
return pxt.Util.endsWith(file.getName(), ".py");
}

export function updatePackagesAsync(packages: pkg.EditorPackage[], token?: pxt.Util.CancellationToken): Promise<boolean> {
const epkg = pkg.mainEditorPkg();
let backup: pxt.workspace.Header;
Expand Down

0 comments on commit a2e4ee1

Please sign in to comment.