From edf361ce6c99f570e59677f7a0e650fe7eec89c7 Mon Sep 17 00:00:00 2001 From: Denis Bilenko Date: Wed, 5 Mar 2025 15:18:59 +0100 Subject: [PATCH] fix bug in Version: line; add "selftest patchwhl" command + acceptance test --- .../my_test_code-0.0.1-py3-none-any.whl | Bin 0 -> 1832 bytes acceptance/cmd/patchwhl/output.txt | 6 ++ .../METADATA | 9 +++ .../RECORD | 8 +++ .../WHEEL | 5 ++ .../entry_points.txt | 2 + .../top_level.txt | 1 + .../cmd/patchwhl/output/src/__init__.py | 2 + .../cmd/patchwhl/output/src/__main__.py | 16 +++++ acceptance/cmd/patchwhl/script | 9 +++ cmd/selftest/patchwhl.go | 24 +++++++ cmd/selftest/selftest.go | 1 + libs/patchwheel/patch.go | 2 +- libs/patchwheel/patch_test.go | 59 ------------------ .../my_test_code-0.0.1-py3-none-any.whl | Bin 1909 -> 0 bytes 15 files changed, 84 insertions(+), 60 deletions(-) create mode 100644 acceptance/cmd/patchwhl/my_test_code-0.0.1-py3-none-any.whl create mode 100644 acceptance/cmd/patchwhl/output.txt create mode 100644 acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/METADATA create mode 100644 acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/RECORD create mode 100644 acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/WHEEL create mode 100644 acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/entry_points.txt create mode 100644 acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/top_level.txt create mode 100644 acceptance/cmd/patchwhl/output/src/__init__.py create mode 100644 acceptance/cmd/patchwhl/output/src/__main__.py create mode 100644 acceptance/cmd/patchwhl/script create mode 100644 cmd/selftest/patchwhl.go delete mode 100644 libs/patchwheel/testdata/my_test_code-0.0.1-py3-none-any.whl diff --git a/acceptance/cmd/patchwhl/my_test_code-0.0.1-py3-none-any.whl b/acceptance/cmd/patchwhl/my_test_code-0.0.1-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..4bb80477caf51393354453b18c0c88711098825e GIT binary patch literal 1832 zcmWIWW@Zs#U|`^2xLh&ryk0?NcfY>3uGYCT z=ezsEH-rWlT`<029P+5E-(N@fdGY9=0ryhVJ$tvvUNQc+{d3{D zn|B2?ro>EK#LF7E*yLqccPAsi^Am}D%e30AoeArVlYJ((&Chx9t8w97&hq5+iY(pM z?WKI0`Ng-xP8DwL5?S^qs;1iP{ao7%o!XY-3yZ&e5Ut|$zxe;x^oV^&AD++Fd7iem zR(X?DP}|ALQzYCuG|lZak1|#q*u;_lsY}J+e|O){(NT&M^DqET*~S;Ni)SUsN4C z9Dn1{?j=1*vsGR>2Ap1Urdi@ME2@w3r*1Nd0r~`ll?eGL+{4w?hx@#T@7asIkTkJ5 z$l!|cgChU4-nw2oC-pZ4d3c@F(d*P_Um1A8;DWK?CF2WExK5qdzxY+>8n1?~*V&Uk zn}RenwS1p)dHQS*(pX_~?d<9E-dBCktbX!{2`Tk}Lc4^`-&YapE?q)yOU)}Os*Eql z&&(?+)+?zf>Gsnum6bPz^n=Yu)|leb1cf?%&Q77=vb)*4}*!*?@Mi z0I?P!yGrs4;&W2VQgc8SY3q4CLw9*{w)FQ{Mg|65CI$v&LZ$_|I{OE?w4OU%)MUWm zaB=T_A&mrw*ph>*mAaB@F8Q(@M!#{WU5W^A%QRiSMW z{ozJ=^Fq0UM|XJ53fr~pZf|;Euh=Z{Z-Tx4a;F>EwmRNScHD8mvs7)8lJ+L8`I_QF zshMAec0^w`-2TiwZ^_?(T*a4Um+uz%9hJHAo6n-@<%iYQ%+*hCy{@^uvZID|#pH|s ze;h2ndvtru#jke9t4>^Ne8ji;gOB{FCkgtet-sDum^X=S@}n%?$yyAP)vvd7E<0Z8 zI`hG%7f1XLTdv`o%)7mde~0q)?pa+LTXvaz|5|P@sQzMo+2)nERD@WZf7CmNnCf|W zcinFk%sFDWcj{{;(KVwNY7ngq3`-iL;hNz^9I|F?B?v;ZHZZ*qRi2<5iJpZK zM*byaBsfE(n}?q55a!JUCTF}(M9+liMx*C4gwd?b1dK+>bLi%x=Qo(STN;B2nG4B% V0p6^j+|R%cgo;34egu^R3;+-1eXjrj literal 0 HcmV?d00001 diff --git a/acceptance/cmd/patchwhl/output.txt b/acceptance/cmd/patchwhl/output.txt new file mode 100644 index 000000000..454a19bf2 --- /dev/null +++ b/acceptance/cmd/patchwhl/output.txt @@ -0,0 +1,6 @@ + +=== Test prebuilt wheel: +>>> setmtime.py 2025-03-05 15:07:33.123456789 my_test_code-0.0.1-py3-none-any.whl + +>>> [CLI] selftest patchwhl my_test_code-0.0.1-py3-none-any.whl +Warn: Patched whl: my_test_code-0.0.1-py3-none-any.whl -> my_test_code-0.0.1+2025030514073312-py3-none-any.whl diff --git a/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/METADATA b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/METADATA new file mode 100644 index 000000000..c1ba293e1 --- /dev/null +++ b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/METADATA @@ -0,0 +1,9 @@ +Metadata-Version: 2.1 +Name: my-test-code +Version: 0.0.1+2025030514073312 +Summary: my test wheel +Home-page: https://databricks.com +Author: Databricks +Author-email: john.doe@databricks.com +Requires-Dist: setuptools + diff --git a/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/RECORD b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/RECORD new file mode 100644 index 000000000..2f6e7e51b --- /dev/null +++ b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/RECORD @@ -0,0 +1,8 @@ +src/__init__.py,sha256=BRmKeYehopKv4NG_SFa7t6wn248RrPHJivu7DM1R-Rw,48 +src/__main__.py,sha256=8TtsnLsaJEM35Y4L8ocrv-qfxusgYpRL2HPyYiabHng,242 +my_test_code-0.0.1+2025030514073312.dist-info/METADATA,sha256=nidQMSt6OxDHKdNCQGq1Kv_AmJa1ldwCMHRqPk2TFD8,214 +my_test_code-0.0.1+2025030514073312.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92 +my_test_code-0.0.1+2025030514073312.dist-info/entry_points.txt,sha256=oDWOW9SsBlk4Uejj1ftYPBxfhJ5ZJctb4JOUIG1rc-4,34 +my_test_code-0.0.1+2025030514073312.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4 +my_test_code-0.0.1+2025030514073312.dist-info/RECORD,, + diff --git a/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/WHEEL b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/WHEEL new file mode 100644 index 000000000..98c0d20b7 --- /dev/null +++ b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/entry_points.txt b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/entry_points.txt new file mode 100644 index 000000000..85a57f7d3 --- /dev/null +++ b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[group_1] +run = src.__main__:main diff --git a/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/top_level.txt b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/top_level.txt new file mode 100644 index 000000000..85de9cf93 --- /dev/null +++ b/acceptance/cmd/patchwhl/output/my_test_code-0.0.1+2025030514073312.dist-info/top_level.txt @@ -0,0 +1 @@ +src diff --git a/acceptance/cmd/patchwhl/output/src/__init__.py b/acceptance/cmd/patchwhl/output/src/__init__.py new file mode 100644 index 000000000..909f1f322 --- /dev/null +++ b/acceptance/cmd/patchwhl/output/src/__init__.py @@ -0,0 +1,2 @@ +__version__ = "0.0.1" +__author__ = "Databricks" diff --git a/acceptance/cmd/patchwhl/output/src/__main__.py b/acceptance/cmd/patchwhl/output/src/__main__.py new file mode 100644 index 000000000..73d045afb --- /dev/null +++ b/acceptance/cmd/patchwhl/output/src/__main__.py @@ -0,0 +1,16 @@ +""" +The entry point of the Python Wheel +""" + +import sys + + +def main(): + # This method will print the provided arguments + print('Hello from my func') + print('Got arguments:') + print(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/acceptance/cmd/patchwhl/script b/acceptance/cmd/patchwhl/script new file mode 100644 index 000000000..b9e0dd5d4 --- /dev/null +++ b/acceptance/cmd/patchwhl/script @@ -0,0 +1,9 @@ +title "Test prebuilt wheel:" + +trace setmtime.py "2025-03-05 15:07:33.123456789" my_test_code-0.0.1-py3-none-any.whl +trace $CLI selftest patchwhl my_test_code-0.0.1-py3-none-any.whl + +mkdir output +cd output +unzip -q ../my_test_code-0.0.1+2025030514073312-py3-none-any.whl +rm ../my_test_code-0.0.1+2025030514073312-py3-none-any.whl diff --git a/cmd/selftest/patchwhl.go b/cmd/selftest/patchwhl.go new file mode 100644 index 000000000..25a792952 --- /dev/null +++ b/cmd/selftest/patchwhl.go @@ -0,0 +1,24 @@ +package selftest + +import ( + "github.com/databricks/cli/libs/log" + "github.com/databricks/cli/libs/patchwheel" + "github.com/spf13/cobra" +) + +func newPatchWhl() *cobra.Command { + return &cobra.Command{ + Use: "patchwhl", + Run: func(cmd *cobra.Command, args []string) { + ctx := cmd.Context() + for _, arg := range args { + out, err := patchwheel.PatchWheel(ctx, arg, ".") + if err != nil { + log.Warnf(ctx, "Failed to patch whl: %s: %s", arg, err) + } else { + log.Warnf(ctx, "Patched whl: %s -> %s", arg, out) + } + } + }, + } +} diff --git a/cmd/selftest/selftest.go b/cmd/selftest/selftest.go index 7d8cfcb76..5e2a2c30e 100644 --- a/cmd/selftest/selftest.go +++ b/cmd/selftest/selftest.go @@ -12,5 +12,6 @@ func New() *cobra.Command { } cmd.AddCommand(newPanic()) + cmd.AddCommand(newPatchWhl()) return cmd } diff --git a/libs/patchwheel/patch.go b/libs/patchwheel/patch.go index 956871eb6..d0967becd 100644 --- a/libs/patchwheel/patch.go +++ b/libs/patchwheel/patch.go @@ -54,7 +54,7 @@ func patchMetadata(r io.Reader, oldVersion, newVersion string) ([]byte, error) { if foundVersion != oldVersion { return nil, fmt.Errorf("Unexpected version in METADATA: %s (expected %s)", strings.TrimSpace(string(line)), oldVersion) } - buf.WriteString(string(versionKey) + newVersion) + buf.WriteString(string(versionKey) + " " + newVersion + "\n") } else { buf.Write(line) buf.WriteString("\n") diff --git a/libs/patchwheel/patch_test.go b/libs/patchwheel/patch_test.go index 5fe27e565..822c3d643 100644 --- a/libs/patchwheel/patch_test.go +++ b/libs/patchwheel/patch_test.go @@ -1,10 +1,8 @@ package patchwheel import ( - "archive/zip" "bytes" "context" - "io" "os" "os/exec" "path/filepath" @@ -182,63 +180,6 @@ func TestPatchWheel(t *testing.T) { } } -func TestPrebuilt(t *testing.T) { - tempDir := t.TempDir() - ctx := context.Background() - - // Set fixed modification time for deterministic testing - fixedTime := time.Date(2025, 3, 5, 14, 15, 55, 123456789, time.UTC) - err := os.Chtimes(prebuiltWheel, fixedTime, fixedTime) - require.NoError(t, err) - - // With the fixed time, we know exactly what the output filename will be - expectedVersion := "0.0.1+20250305141555.12" - expectedFilename := "my_test_code-" + expectedVersion + "-py3-none-any.whl" - expectedPath := filepath.Join(tempDir, expectedFilename) - - outname, err := PatchWheel(ctx, prebuiltWheel, tempDir) - require.NoError(t, err) - require.Equal(t, expectedPath, outname) - - _, err = os.Stat(outname) - require.NoError(t, err) - - // Verify the contents of the patched wheel - archive, err := zip.OpenReader(outname) - require.NoError(t, err) - defer archive.Close() - - // With fixed time, we know the exact dist-info directory name - distInfoPrefix := "my_test_code-" + expectedVersion + ".dist-info/" - - // Find METADATA and RECORD files - var metadataContent, recordContent []byte - for _, f := range archive.File { - if f.Name == distInfoPrefix+"METADATA" { - rc, err := f.Open() - require.NoError(t, err) - metadataContent, err = io.ReadAll(rc) - rc.Close() - require.NoError(t, err) - } else if f.Name == distInfoPrefix+"RECORD" { - rc, err := f.Open() - require.NoError(t, err) - recordContent, err = io.ReadAll(rc) - rc.Close() - require.NoError(t, err) - } - } - - // Verify METADATA contains the expected version - require.NotNil(t, metadataContent, "METADATA file not found in wheel") - assert.Contains(t, string(metadataContent), "Version: "+expectedVersion) - - // Verify RECORD contains entries with the correct dist-info prefix - require.NotNil(t, recordContent, "RECORD file not found in wheel") - assert.Contains(t, string(recordContent), distInfoPrefix+"METADATA") - assert.Contains(t, string(recordContent), distInfoPrefix+"RECORD") -} - func errPatchWheel(t *testing.T, name, out string) { ctx := context.Background() outname, err := PatchWheel(ctx, name, out) diff --git a/libs/patchwheel/testdata/my_test_code-0.0.1-py3-none-any.whl b/libs/patchwheel/testdata/my_test_code-0.0.1-py3-none-any.whl deleted file mode 100644 index 14702281d87f6180c03799b19ec1ab6a10f95509..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1909 zcmWIWW@Zs#U|`^2*jp?fe!}|sR6QWi0Ei`kIJYvsB(=CCJ~=-nRX;vHGcU6wK3=b& zvb$g3TUYDcne*NK;Tu8&j4l{oFb;Xt)$gyPd-8;S6UQ!scPxs+J%e^0VsBe z?D2WA7-;q<>~`cPX6AwI2<_X=cSu2`t$f}ie!eZ;{1=vN?&DMITQaeELIL+u(>;5) z$X+r2xBYYBxtn(dG^WH%T*S*7xY*=nSa&BQzw;A`e9N@juAK?%jFWvPw$0CZ@vCv+ zUC#34^olIq*6pQyn)$`I!%h`$?Gjn`C#t5}?EPHZ3!U1Q;tPwvd=RbT^uPH3*Yt>e zM<1Tg)_I<`wpMwQR8ZT=$x|fUIW*1fG>RX#;XTV4(hyusmi%+F9@wUD;JW4nu!?^$dy zymf_ll8nmFA_hkt!=|h^YuC#bJFA^;`|kbeX>&dRJ69 z$LIY8Z@pKnw6_ymom8!NL@#1rQkVUv_Vm}n6HeJ~oXB#=tVhD5W4+QnRF8HC7_Eu{ zdJu$_2zfNz!`0P?`@Dzm*^9i8G_yI#;EM5sBLB1Ax?Vab^*051c%9VI>(pmo8F<0q zg0b0k;|ou?PMz1k_*Lf`uZFJI*^@q-f;2R>e4lc8`fLxF(do6c`hOW@qmTJp+EAUA$0x@kV?}enEUrYFTOy$imY| zRy;-bO4j6ipW_%A7#x@w7?cTlCCJs;Kggx^!s((W1BTXzwewju6GS3P6a`)N*1GB} zo6R$|BhW*GGw|1!x5sAg%8Y;T`}~}=1Cuy9zwc4$mk4%KJyvC%@hBo<^2^E7%>*5v zoVe}L_+0g#4p+3F{uw5}TWgyqthzT(JRh{-dqHsOvazjxvS@7*ijT2DGQG1vS2$uXOsx>kEV}tyyM^QLgJ<_EQLtFYDR9(i4JT8T(!p zvsMQSZum7N^~wA&w+~NeY*}qm{HI*u>qBp=>s#9M1H2iTM3`}xmcTdygC&h13ON-Z zm!0UQpqGabGZ+|_G^Svh0xunrO~F?9AWX3ZCLv_E;4F&JjYQAp2qV>iDH5-d;7pHh z9(vY9n0JVfdFUAx-Dvb2h%nlWnSfJK@*}#r=vfeE?iR*gLgqp;WPmp-8%Ps75E=u0 Jsly850RXT?oKXM(