From eb4c9f2b006d43d7a6eaa3e7e7b6f6f1e2fb8a17 Mon Sep 17 00:00:00 2001 From: Tristan Poland <34868944+tristanpoland@users.noreply.github.com> Date: Tue, 14 Mar 2023 17:05:45 -0400 Subject: [PATCH] Fixed library to be packagable, added logging, added workflows, corrected spelling mistakes --- .editorconfig | 20 ++++++++ .github/workflows/python-publish.yml | 39 +++++++++++++++ .github/workflows/release.yml | 26 ++++++++++ .github/workflows/test.yml | 30 +++++++++++ .gitignore | 13 ++++- ...0e381e5b-9409-4ffc-9c4e-02d580443435.vsidx | Bin 0 -> 38578 bytes ...2667559c-c77f-4162-9ef3-fef940b13df2.vsidx | Bin 0 -> 197 bytes ...5f0240db-9267-4a3c-9bc0-bc9b9f4fa559.vsidx | Bin 0 -> 335 bytes ...63424c4f-3749-4dc3-b82b-7a73206eef4d.vsidx | Bin 0 -> 4855 bytes .../FileContentIndex/read.lock | 0 .vs/ShipHelm/v17/.wsuo | Bin 0 -> 29184 bytes ...bae79108-9b47-40e9-a4e4-d14590be1602.vsidx | Bin 37578 -> 0 bytes .vs/VSWorkspaceState.json | 8 +++ .vs/slnx.sqlite | Bin 90112 -> 90112 bytes MANIFEST.in | 4 ++ pyproject.toml | 3 ++ setup.cfg | 3 ++ setup.py | 2 +- src/shipwreck/__init__.py | 0 main.py => src/shipwreck/errordetect.py | 8 +-- src/shipwreck/logging.py | 47 ++++++++++++++++++ tests/__init__.py | 0 tests/test_module1.py | 11 ++++ 23 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 .editorconfig create mode 100644 .github/workflows/python-publish.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/test.yml create mode 100644 .vs/ShipHelm/FileContentIndex/0e381e5b-9409-4ffc-9c4e-02d580443435.vsidx create mode 100644 .vs/ShipHelm/FileContentIndex/2667559c-c77f-4162-9ef3-fef940b13df2.vsidx create mode 100644 .vs/ShipHelm/FileContentIndex/5f0240db-9267-4a3c-9bc0-bc9b9f4fa559.vsidx create mode 100644 .vs/ShipHelm/FileContentIndex/63424c4f-3749-4dc3-b82b-7a73206eef4d.vsidx rename .vs/{Shipwreck => ShipHelm}/FileContentIndex/read.lock (100%) create mode 100644 .vs/ShipHelm/v17/.wsuo delete mode 100644 .vs/Shipwreck/FileContentIndex/bae79108-9b47-40e9-a4e4-d14590be1602.vsidx create mode 100644 .vs/VSWorkspaceState.json create mode 100644 MANIFEST.in create mode 100644 pyproject.toml create mode 100644 setup.cfg create mode 100644 src/shipwreck/__init__.py rename main.py => src/shipwreck/errordetect.py (97%) create mode 100644 src/shipwreck/logging.py create mode 100644 tests/__init__.py create mode 100644 tests/test_module1.py diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d9de0c9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.py] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{md,mdx}] +trim_trailing_whitespace = false diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 0000000..bdaab28 --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,39 @@ +# This workflow will upload a Python Package using Twine when a release is created +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Upload Python Package + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + deploy: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build + - name: Build package + run: python -m build + - name: Publish package + uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..91100b4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,26 @@ +name: Release + +on: + release: + types: [created] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: "3.x" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + - name: Build and publish + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} + run: | + python setup.py sdist bdist_wheel + twine upload --repository pypi dist/* diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..7be9344 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,30 @@ +name: Test + +on: + push: + branches: + - main + - master + pull_request: + branches: + - main + - master + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python: [3.6, 3.7, 3.8, 3.9] + + steps: + - uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + - name: Install Tox and any other packages + run: pip install tox + - name: Run Tox + # Run tox using the version of Python in `PATH` + run: tox -e py diff --git a/.gitignore b/.gitignore index b6e4761..a81c8ee 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ parts/ sdist/ var/ wheels/ -pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg @@ -50,6 +49,7 @@ coverage.xml *.py,cover .hypothesis/ .pytest_cache/ +cover/ # Translations *.mo @@ -72,6 +72,7 @@ instance/ docs/_build/ # PyBuilder +.pybuilder/ target/ # Jupyter Notebook @@ -82,7 +83,9 @@ profile_default/ ipython_config.py # pyenv -.python-version +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. @@ -127,3 +130,9 @@ dmypy.json # Pyre type checker .pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ diff --git a/.vs/ShipHelm/FileContentIndex/0e381e5b-9409-4ffc-9c4e-02d580443435.vsidx b/.vs/ShipHelm/FileContentIndex/0e381e5b-9409-4ffc-9c4e-02d580443435.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..1329353273743245f3a5116ccaee167e89edb9a7 GIT binary patch literal 38578 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 literal 0 HcmV?d00001 diff --git a/.vs/ShipHelm/FileContentIndex/2667559c-c77f-4162-9ef3-fef940b13df2.vsidx b/.vs/ShipHelm/FileContentIndex/2667559c-c77f-4162-9ef3-fef940b13df2.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..64b6cb35bcef76bf019893e2fa7730548ad1e70d GIT binary patch literal 197 zcmZ>Eac5y*V3-NSAOK>603#5?*vvq-7f28Y+<@4{D#j&0ximL5ucSD}J+s84G$|%H zBeTFGH77SFC9}8$&eJu}Gtslq^~f(t%dF5VNi5P!ueyJN$@F*NO-7jM96%FcY*vsJ VPyk}{L)p?$S{+JPLg`j04FCXP9pnH2 literal 0 HcmV?d00001 diff --git a/.vs/ShipHelm/FileContentIndex/5f0240db-9267-4a3c-9bc0-bc9b9f4fa559.vsidx b/.vs/ShipHelm/FileContentIndex/5f0240db-9267-4a3c-9bc0-bc9b9f4fa559.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..32aa35f218208052472aa35daece791ca4a5ba1e GIT binary patch literal 335 zcmZ>Eac5y*U{GcR5ji*>TwG0{ zDh+_Ni&czEesXDUYFh0*}-HXfP) literal 0 HcmV?d00001 diff --git a/.vs/ShipHelm/FileContentIndex/63424c4f-3749-4dc3-b82b-7a73206eef4d.vsidx b/.vs/ShipHelm/FileContentIndex/63424c4f-3749-4dc3-b82b-7a73206eef4d.vsidx new file mode 100644 index 0000000000000000000000000000000000000000..1a12c3fba32e30ae86741d29d5673ac2f83758ba GIT binary patch literal 4855 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 literal 0 HcmV?d00001 diff --git a/.vs/Shipwreck/FileContentIndex/bae79108-9b47-40e9-a4e4-d14590be1602.vsidx b/.vs/Shipwreck/FileContentIndex/bae79108-9b47-40e9-a4e4-d14590be1602.vsidx deleted file mode 100644 index f32d216ec3f9f202a1877b44096c5e0f2a56ee20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37578 zcma)_378yJ_4XSCWR*pNAPAvBW(KBvLJ~p}h<0_=?e5A{S5>O2XQm-KQ8pDpL_`rI zLqJ6lMHCfLh=_>$h6|#iqJq1qAc~5jqT;@Q>Km6Gq(~YPH%mSJ=h=A&r0A+0WA+!({CdhWgleed4(K%4PK+tp{a2sOq7shrN23 z)gxDr;(8~p_o{l_ug7V9+SL<##q~6(r&&E~*Yl!YX7zGVFNgJNSf2^%vsrzZ)lYEs z6Q5Mym>zb_n#1z=@O(H{pBx)&j*Z)E<5+Y3*s|tWqe)PonG0Vn-iSZyEZ%>Se6XTJ+vT-*t?&iij z_3?OOJdVfXbUZ7@i~4vuF#)^RZm!WO8gai7r;YVlBgq z%@t$KRb$O#$C|6hnrp_ILEdZ!&Cp(*W|%a?tQqy2uG@5J(-loO*X(4?ZnN2qo86+> z3!1%QGftav-dvwG*O$#CYxaX?->$=Enl-bcna9mMZRS}sA2y4uSq9BAY?iKBS~_o* z8=B>yS!K;?t~ukHv#vSUpPCv>P0da%Up}>BJg>hNCaddOV(UAr6nB`4VTT#0% zU%srpeEACdZ~2O2mal5B7@J(tSihpVYDM$d70uNvnrl`pU$tW8>J`T+00i? zEjME;m#8jW0oyDX7%!8)~r6J6RaAWT(u%xwQ_3J>NTs{D~}zU zJT`Kx$0k=VKW_D^)vMR6Tr)Pgrm=F((b1ZfE7z=^ToVLqr>53!Opl++kB|H7>MPgP z!*%uEy0K;J#)5TY-F0K}y0Nm=4T7=BU@8w*E)Q0%u)z=3932E}f_5CVlc1diVHkui z2zx;|9fVa71wj-Akqe?Sh-Lz--gQAY4!T7UCqdi~;xvfMV0tQ;cENNUB$GkX2@*>r zL6QYY9wcRuR6#NblKG$?1br9u`$0bs(jZ8~AdP~w8>DfNra@W;X%(b{ARPvI5afA~ z4}+o^6jMPF1VtDWQBb&`=mtd`6w^V`4~ilv%Alx%!b;8ur3=b9D5rxm3(7JmtDtHG zRWqo9pbCS^1yv`gdO;Njm1PZrYCaf5!5|3+WiY6MnIM>P!Au;?mcd*-m~+8!vfWtI zZiek<*$F|3?c%me+AeLoq8%sgIBlqC?LD?QuZEI^-wdce3d=f5OZi5#FZ5xa*NGwd& z`7kK04`DC}Ll=fw7!I(jxrxwChHff!?a)P`i$j-$E)88Cx-#r^!`^tls9BGiVKkLR zK|2ciQBXy}Ow?{hk&B`@a+BD-ToaP(L@tS3KXPg0^2imDDjhR}x1hQx)L1=NKD7u8)f z>7u5K*1E`9uUurxdFLiga4vDK?_BC!;auf9f$KQeiCrgi-N1Fbt{b~<;(CFLQx_L5 zu3S9hl7>qHgwSdy9hbx|NnDb-q;$#9*%sapV6~sRe(w4uW}HRZ8c8#knpnAX;L;hF zbzD}sJaD;ldE)ZSPyxVg~HIX9QPxzf#5Zs^=_vzw2cg>yc2^SPU! zcbmuD=4Pkf=+wi`#M(~Nb(&=-SlJ1}P7rs30Rrq&>qf_wozB`$$8|b`P8=fYai)S#_t9ZV-0^yY_91>;_fW)w^!eCS2D=UDxlrwCl>QtGe9= zhP_*MdsR11yRltox=Gwk*LBmNo5tNN>t-{y$9D_YEwXOe?3PpAGVTt7?x5ct6ut4H z*X;J}1`~|+f}|Iuy`bm?rR}Y~V5aAqJvW8T#zj5ndM@s{e$S;nm-SrHbESp8=jO2$ z#YrztdvV^2i(Xvz;+b9+^|GXw^?O;`%d%cp^s=&-4SLyZugH33)vG3ZRlir2y{hUB z+Pz`k+dO7>FT3T~UBq_wxIGoOSJ_@1x8oR_Z(%!Z98ShzV4EY_4C6RVY$uAtK^!&W zsA+pg993~Nz?Oiyp4$Ag*%NmhhN~0DohnAGn-<@=>*8)N?#31`i%1+##P%;)hx=g? z#fgg(6O%X@#K{nM$i9pF-MAme{XFiMc9e_LN!&JV-?hER)|^cQ8-z5D)AeyW9jAGm zTCpllXX11&&eAxajPr(_iQ?SFc_+@}IIrS-HqM9Gx@^f7SzHuxS&z%fxNOAb6t?ry z#bq3q({Y)_WgeGhTvl;49#<1_)r_kE3%%;aRUB7IT%~c9#Z?(sR%Q@a!?>D{2mN>^ zu+1QziQ~Do@tlk2HpeHp^+CGch3m6;eKuHMX6py}^w{L|_{4OxGaYoNqiotuPP=H@ z71OSocEjnoW4)Trv+1%vT~1Dy&FS*Eq|r~-joFz4w-g*E(j+L7piF`)31*XEX!n&Q zn!*kgl}R*3)#(gVatf z{h;ax!+zWK+crBU`mWh`>u@r1Vc$jAR$bb6x$S^`SN2`icbofhw;!kdxa`MOKR%&9 z9rcs2pSXVCUU9#l_4|W<8uzoPpQZh*z+B6dexCJnOAq?xWPgzM2W5Ylr}c?+tV+jS zI$oyZRoZYVPWdxwV>WHpQ#(YitEcP6(x8paAV|`np9V!5RB798&$iRs%uVcmpN3T$ z4(x`VM&oHTnMPB%1K@_5*qt(s2C17!-P+WJsf%!DaGlh3QC99*6W9$6i*nwcBqy`+iOe3Enss~d$XeYjh_d$jtes?S zJK_X(KC@$17EWhjX2&2qvXbCY&(0_ZD!px*$glUdrx(q@*f&C+#Q8sHR@It#i5+9HbyZu14vwCGs>XR>rY%c3ls#>CIcEN^7F z%kntO`&pi6d6DH+mJhOgm=$$h}N%gQ(_%d85r%Hb|o^|C6?s@ZH%&j#IWkYs~28|2xb$OdILsIr-< z%nlSYaW*@V&AM#X5@|L&pUq8W_QWuLbUtnmrBU8+c_Yaiv-w(k&aqdR2i-g<@}SDy zWbT68g*c43BzI}sX$Zc~<4wES^_jE_*pMzqScc@<#8M%dc&EN}1IO?n!fiZ=iy$e2ei5WaklRyJ5mZIn9xB%1%oX;EFfPKx zj_*a(;4NjWaLvL^;d#ro3l|nH!qLo*A$B6bF>$(ZN#Xj1OEKU$)omzTS-7fjGesw` zvrEyPD!Q()MbQ>F&`K6X?f^GIW}32Pn6?jIWbvItSuX1*@((UUN-AxGr*bD&P`1d=Wx@Q znlIN*m1{Sa>rO1~;VfH zi*TyN5!`mQymTAjJ5INDklkG3tZ7FjJA~Om%GOr9j3XR@wRZ&)DSy_SkauAe*b~y-f9v^heL0k@!(r!?L zyqs;8!?YZh<@|g#Ua!VG)p%Jo%w8Rjk4;-fQ})DM@r?@BJ3#yM)RsF@V3ODQw?%NYfx3QK{Xp!bCtal zSq&$vVWS#0t6^Sk9IxiX${uLuJJtL=4(521r5LoEgZBDCI~lb52y=U2Zxal{-XM$z zVKs=HJ>m}Bq&*)FoUPph&U96$Rc_Dczuq?PN6I{1}vjLFFvC zgDSQieNdG%haEH1Y~z?2Br`!V6I3&9a>hmW2#T969{I|dIJAdsyYbp`oQcbsES#Na z&K@-}+YDx#z1g6c4a!;9wkN|`H#6IFv%PrM9vJXkp3KJSY+PChXK~<2X0u|paI-}` zTMlMto3r+BKA)>k&INru`Gv_`I6vnm=Uh1FiaA%#^^>{WUd3E#%(R^Y_7*>1j(@NhV8*H42F?CGN$%`I_%i#KOLrRJ4p<)!7vYoxf|x$FfWGra9Fru z5f97eu&jpmlv(wL`1hpYiQ#ZQ9Bv*v!A+jvq7z(kVwjzn1}6@Oc<*_9uuyoNg+6n>KAaKd8=c2j_R<^E-p{r``Ge?EINv zbA4iSv;JrQc6)7^F!%!&w0+q?$gidJ@=^_%cnj4tmmD5%1NhhY@YV? zbDnH&@!~oWLyGpED7M5v zY>S~7iI}IT*Acr$j6*DWy*MoqWuNqPR>yp1A-YI@l{FeA_@hd zO59W2OWfOt^|`O)CE|YKW5oT%1H{LQ2Z{%Yj}s3T4-uD&hl+LaF!6Bl@!}EUm^g04 zJUP+`e;dXfj7LjeDIP2RaYmG1Cq7a6ZKJ(vp%{ry>=<{n{AtOF5q45BmwtofQgS5@ z#2Il`oD+ve*gMgPb~Z`>6!EFzN#e=kDdMT(X-4$_bji;&!tR-ppJhax&Nialx#A0q zDEC66y=t2!Um#v6{T3tYy+ry;jIej9@?RldCcaX9l@az|E%^!~?7Ys1`d2CcYURI4 ze6#e|O5Q5@IwR`6P5K)ozeD-&lK$P|dyI(d2PJ<V1ze~aW#NWRqw zzi*TL1?Ar^-XVTb{E`v&zhZ>FuS@?8@lNrZ;&_;(}h z{8RG3#D7cwAIT3%-p&eJvbMeW2qVVfk&<^7cM*3LcN2FP_b}S4wx{I1jIgt>^!rKw z7;%5`0OcQOME?$!{t$7gc&Jzx4-*eJ+N*Yi0c(kT)b5Imq~u5%}*SSBY;FuNL1VzFE9R zyjI*QzD2ywXs_D!lHVrYAiiC^QGAE^PVrqv#PPl22aNWreaJ3|_f1BO&&|@`V#GM! zD)}?wZQ|#RsP_f&cIm$;`Ag!LjcE64;+;m=y-V^vM%ekT(O$KCC4XQ1f%NxD{*m}& z@qXq1RD3}Eh4`Qm_J1Y*TKtXpTO<7WqvSt{e-{5D{?%x&+TSJrL;R=sFY(_-d)59U z`5_TOfFIk5+l!A7cMx|JcQV4x&XRW#cNKRNcNg~%A0_T7?j`Om?jt_h2>VMU?a82xe;~?$))6hM#Sq>@ie2oYR`~-y7)}-4Dn1O;(xYyuJq3{qW$xv-)zJ>-=h4B z#EZoji!TvhYDE2)8SPbjh4hz6|0?OP5U*7J>y-Zn$ybSQG}^27X35tWVSlT5o%C-N zub2J?qrGbHkp7+0zuSm@zhAsb`i~e9$B&916K@tjF5V)3!U#V;CHYn(?A|8*=f&HV ze~0)*>A!5WSM6((zhOlCcZ%OM+N*Y#U10aS(tl69SNy&ae*DmAuiB3#|3v(m5q2Mt z{0pPKYQK{H*Wz!Cu=6{ky=s3H|04b0jIi@}$^Vr6FY({v|0w?<$#5R^wiCA(A0h4_ z?kMggK2qFS+(q0~+)dnF+(UenxTm<6xVN~E_-G^kf#zy$KO_3Tzw!@|e4x=@wL>Hy zYD9nPM$~(}ub5>72--G{8=UWSaG${UbW-xg7%*%eG5wa z2clkE`cRBSCw4@9@Brmw$?L^w>HCsXF_V6SSV~`s1L{JQuJ<$qKBw)A(2cZ=T}*h{~-B~;-94di{!sb{=4{3qrGbXu?yzILn0Op^g9@# z-%;F2e5AOuxQh|}*j@4-M)jj%H={e*a=c$7G4MENOkxe@KHG}^1SMtp+wEhFL)h;1=6+N;*H3))Sj?~AF? zUbRwkB@VC!(_JVQKF`Dck|OaC14 z9O=(B!jJRB7b<_V_#*KFBig;ti1HU3;ol{aFEt{5uMjU2Uui_W%f&0Ce~tKB@k;S^ z;_JmX7*YR?lCL(R{c9v&EBQJj%3Uw{?aIGVe24f>@m=D(#rKHs72hYmU;KdhLGeT4 zP2z`*_y@wjk4b;C_;K+T@e|@F#ZQU18d3kVl5Z0~C;jb`?=ae{_Eo!}-(MH+6u)J} zczj#DOT1h8_elP(_&xDnBgXYU$v+Z*EZ(pD2PFSo{Dl#IJShI!2s^)5{vV|OlM(&< ztMq>p|1SQ+2s{5WqTGMP?RN70+1`l!9VG84`H|u-Mzp(!QLOOT|OQx_Fp)xcGP@{2G%yF8N5wM~RbSLu`su;xh4QBm7<|`51APc&xZu zTqCX(j}wm<*NIOs!q1l2mOd0CBiijs?imrMMEXqnT-+cQVkuVQK%6n6-8u0DBkVp| z@+R@A;>qHvMvU8O;?tymh7o?AA)clDXNzZx&k@ftqWyCvKhKEzFOYn`_(CK6T2TH) zM$~(;_)_IxD!$4H|1K9_EnXqMMtrS!rT97{+P_Nj8^x=|H;Hc+uMw{mw~B8OuM^)Y zUN62)yupZm+-OAq-Yxxm#P^EtQ~rmH@b4qy%|_I}Mf{`@{r;4AtN3ZybhCmxcGSS z2qWr`8{yZa5%#B~KiY_XE*DoQf0ejK`nBS5;_>1-@d@G+#g-Tt(S9g75}nu)yJAm_ z#r5K}m>6L%m7Gc5AePcs;y|1cXT>=q?3`dkJf0+Z-iSDzWJFv}7Ee+BX_B8NK3#l< zc)Ahx&XoKt@htJ#;@RSJjPT>RlFt>NCq7?1Pke!Rz7h2{OMa1ffw&-EXhgY-#1~8d z67i+tB}Vl76-M~~D(NpbqW%@)Yo))^h;na`{*BUKExt*7v+}PM-(p0)>m}b{M4aC) z-YC99e5d#>BkH}^2tPk)gkLu)|HI-(r2m-Yo5hcdwp!=*QQ@uSzMFml1aUqx^@Y-)?7bZ+r0(;tocXf28D{jfl^#l6O=7 zqa^QXM1LM_M7br>?Y z4e6Ijf3&z<`eP)o5|1^aKgUTv-Uz!-G@`vg`nDK~k?4#l*OlB8W9g?QCq~%KjA*Y^ z{y>~HV!Y?Xp?HFLq7m&p$%y&#ROwHW{uIflil<5cbn$fY4Dngwv&H8a;n(ww@Z*QL#aD=ziLVr2C0;JRTD-ytyH^^~?(3z0 zgLswrM)7JR%3mY-T5+rR7V$dqt>X3K+r%5hw~IH5?-1W9zDs$7dzqCVo!*y!Ztp%H1LPi;}-A`77dA#jhDL z?%y)Pue*(?e~dk1e@gzh5$!%CJ^sKQ@*|9x_dAF?iaQx$XJ^T~h`WlriMxw? zh>sHYG{XKqM%dX``X%Ci;$xJ5faJ%D2Z{$N|6s|7h)cyom4BEKaTt?4As%IfA5F>2 z#O2Z-V?_T~iN}ho#WmtuBl>Z?5%!)awv``>k?4#l-<8}m!oNiNRQk*adxhjuti*vh zBhHF*;?Rit8;xl1$e5QDYc&7L)@htJ# z;@L*nIY;ty#dF2yiO(0$Got+Yl3yrp7GES@U_}47NWMtC*ogWsk^EB0FB2~nFH`<2 z#aD@!i?23f+^#gj-s{Dy#H)>%KW`G>Ed90OTg102|9bIl(!X7NhY{_(NAmlO=+_60 zu>T?PCh^1KN5qdB;or?h*!iRp^*^or&xoHj;vWdRw;56I^OCq`kJI)>l-oh_j^a+z?<{#2Bkb-jc@ObX z;+{s>*<12HlJ^z&lm0Q{{^9}RW5ol-gT%*)2aAV@OO0r+F8MIYk2fL?M@pVlena}@ z(yx^M7;%+&thicSBd!&X6OR|yiBB*hK7kQ_g`zXUpY=wJZz_Fm#5~<#M7>J#z=(1~ zBkDa_`A?C2suA^06Q5>8d(V)3y5uvAuzQx|vz7lG@f`8FMzr$+@dD`=#0$kO;zi=c z;){)F|D}>Ik^FKa+P_TtS4w}mS5FP2z{ekBA>NqTa_P-y(iO{G|9P@mBHEMzsGq$)6X$ zAl@$CA%4+_cD`anzrH5@*Trv$cZ%N>za@TKyi2^>2s`&k{;v2v>A!D8d-qBIBk{-L z{o+r=pBhpA=aPRR{!;p1Oa6`cTk&^B#Nkgy`12R(|0@2?2)qAO{=X$ZBze2te7#4A zI~uVbc9OiaPFZ(Ts%Vh2_yVJQannW6dPjGi2BPUA1yAIex<-8^pJZ zHyUB@os!=rzFT~c^4}-<{o)724~icWZxTOjgx!xy{+M{P_;K+T@e|@F#ZQU1ik}ug zBYsxAP5hkrdGQP4?cyCq`12*nUlzY2epURM_;v9c;+^6*#czq<7Vi@87QZ9jBYs!> zo_MeLeenn455@b$ABjH}?-zd}{#5*#_<;Cx@fYGR#RtW!kF#LdKb#E^mmRQ)Y{wL) zQ46V^q1yo|e0rmXKdJRa@F9{KKC$I? z){()6*f=jO=;+3-D1uKn)V3^Ip&R>BL`KhkYWBW>E;N4xGH75aQXPs|2>1g?f5D$5 z*6{auHKqng?Z8|VW*e6ywSddcG_aUD9jP8JG>=b%DRfBT!)ab*r}5ds8van6pEC58 z=_EdcRby9oL@L0AA$b6)ePN!KTS)Bs5bZ6cJ(Qz}kL=bK7B3vy2O!eGk6^w9F+hqv z@*;E#xU_KDmqyXBZ;0YzLkpt}q+0glXX41oi=o^8VOCfUH8@ZGWPsE77(~sBv^Nsr zWQ&)P?*CDPo$*F#;9)gJb(w+z>`dDXJV($E_rnVRw<5d6!mzx63qGx(HWo8{FBdaL zF<|Hxn6a4aC)Y?fGK$vlAr9?u=r3E_Yg8C1A6Nzqmu-3pk=v5rn@p0s|J%T5Q1H>$ z+5injD8f|{Si%poA9xg5vgiwoIEYJF7lrYGvl`m29lB_RHCV*gMK0$!$AcbF^d2C$ z1$*287z6IMqg;IW$*&m}*#MC}r$gM}H_#zwz>R_Z)V4y$hG?F5k_x$8Lih_=A5I!z z4SXu7wg;*$VJ=dvn^J zZJ{u&Fzo)e2!|qEXkZ(!P#BG=T@=aTMhnUXT-Yt>`H@k7%jY`hgroONaSCv``0+(u z`pmiuFt8NK7E;`cx%G_#K`T6EzyaSHMS8&DJ^@DY$s2#8V$?W13<=j!%Q9=*qaiL5 z=CTcrKHcRdM>(E6MqR~c{Iy__yMRl8)>=q$+}Ly8Shlh=xcH3>uHnln_{o_X*Fpf1 zH5iBpMJ`;dMjabxiZyr^@Cz30jwVBbYJSZi#aMX*CixA3-QsWuC_+;-z+ksfj*H2U zK19Da!7DcICqFV4sAJE0fjzFM7IG8l*cwH4a1ZDhXEy0a5Y;&0{7|3>bGeTExeg8S z7)qbnBku;=KrW~EsI}{0l&h9qW#1@P%s`DD7aQUPVMB~FK8sj86_=Y?m=}|3UqKBP z#>b@nv}Kd@el)MHLt##?(YX1rqguqe=sK4Hx0?sL>3#o5l8 z%{Cb4OBVy%vJy4F>%nu1ey$;70amDEYn*Tnbs3U3BG-2T4dDxF{C2Yx84)gi4k5)| zbbq91g>LxJQ3nIm=7gG3!?^O%Embp z{Styb&Oc^wD8^x618VSb=@g`x%L{Knj46uwU6kt_pIh>-jb=6{!)M_*K6T-(EJ2fW zjdLR~$%m8ko(qT3U0AHaq4jY_VMdMNY%wJ8!xup=pWhgE>KIejrDZPIRj3i6u%8>S z(qe1Sv0L0v*~UR|m-d*kfU92%DBR+OgMthOmJ#BP#LaC1=J91DzWa28gX~u*a{U5> z2XxoBh8q5EK=USf*IKAyzdO;mp;m1H7eAY54#|+y*ahBBxZ*i2T2{<&D4YzOQVbKP6qh7E=;v25J!LhH5sh+7yLA*MxG}QK z6fN(*=+II|2p2!nmhhcsV0l|)5yrHIT+T3>@;5`Yfv?Zd{<7FOcc}n1I5K|bK;-z+ z0B=fM;vAz3Q8&lM4;f9N1_R3)oDBCPBSO1$k}<^xRee{tSrCf`Som;=yc_I`vEaCI ziE|703&-@@Zcv1S%qF=S_oj}GqZ~fFU*mftG|FCb%5$_hHyAYrHb7m*fVuml?z?cI z`FFyozq>HShD=qv4k^FRQMhG4+ANV;K&Riktc#1kRU+kmUex&|39$u-I8fXQxYsSvad_n?HHvVIxSSbmzR}~?400D}3K!-w z&OFBk$mQH%VEx*HW$Jdcgnv(l1F$y=(QrAYA4hfEi1mI;yVMQ%;11> z;Y6nLD~b*Il>(#q@hgC#+rsEV$ARaL&fttAV+%4U9>8*o7v3OGhRAnGxZTiu&I9(B z%Y`B{IJr0;>@O!P$C5Wb4gfpD45sMm0z5bnJ?Hx1Aiou&-#3sNJ#Mo5d_eGZ;U9;Q zZM01C_g|X#Pb`a;IVdkdjSEnY+XIhBY?2F>k*r|aPj8gtjNlmYfy3{AFv>P4a?@uZ z=oK<+3%F1>nv)!EK9Ty<2>XT$4bTmLGlVXOffpmi{ea#x;!7|Y{L?3jEM*aNi*ez| z_}R{Kiy04l%x$4A{bSfEF2I!c8FiUrgct)3GN%g7b79jp4%8@@Z!|Ix9O+SEUl$J1 zGW+Y#-e|4Gu)_o2H|Q8~Z{8$rcqqb|&E1x(f?MeVEc5AjG?qU0sLMMY%lX?UyNZkj zTxf;sjXp=n<@mA&2ZbZOI|?%zqvcE|M;iclOm>FV7$$BR0UgJMMtwBs2D-{7IS*Ku zMeyZPexA}RUKnw1*97SIr5K+7~R@-IL+ zl+Y0ZNlrorg2T8ooM8v)I9Cr1`0XD}`fy^5dN9C2X5%cvAhKOg|I4C}T$o1ok6k|Z2 zeITIo{aCcj*0?eLzjipTJRc#{^{Z^LgZ@rzdOwWZ`ZzZjT|XJnBYc&de=~UG3*DtJ z91q6Ni>UD;)bLv=J>~G2%6rd@6OlpJXaHXy;(PuX)a86`S;EJPL&hn9%-YXTn4RJB zV@3-Z7bBZP#v{{K=va=EA%KYQU)ko7o4XzdfD7zK6ybT-?{E-lfTQo%8#+i+m!P!( z{RoiaC~!_b#UyVfM+PS_t@spjTewgc&>@s_xI{3&A5t{66uF!)jJ<=%_)%o&c0`TQ zq-mMtYxn_$DY_P-9PLHWvF-wNr%;4tE*IwR4ITaCETIQWOr>xlmqkYHdWUEV7mgs$ zYg{C>;%5Y!T(BQ)(rgzsTF~)w14IrZtw8b_Tafb0k8#=FM8v;#C@vf~@AIO_3346n zp$6S$4X!+PD?l#2=Vb6B4P68)yzjFd-jk+c2L z@SFzxFd~;5z`l!~a+hKZ9)#{>TzE94lYS<`N?< zexAY#gVRD`PHHy98r(qHL3+9gMcCVrrE-#!fJe<%dcX<}!I%i0DRHHpcm&X}KoHhLI6TYyTpU*JQjh3BZ5c!

K~RI^;ZL~`If9WT{9bYZM*$774c;NP*~5_GyMQpY?8ir!?~$=x>NxMC zMJuEE%pwsTM=nL0r}um~dst!4rjdD{i+1S-!{j>+$GMVO<2<&33(GNTY?p(~n@x`^ z52hG)R%1EFimv4}fFkIw7CVx>eKN2Cig0K3n*u~GCVJX}$m8k-sK$o)u*ZqnGL?^k zA8v$%I_`hItF(u5Y;v^AGhkkXp1-U~B&DgKEd42KRBUWIq6?#!in$kduqSJ`puWZB~*EnJr1!WwjKo81-}qnQ)2oT+@oeFrf{(Ene@C^X6a>gBY8 zVPqG0VK`Zhy8ym+t;U-na~*ORSO#nqjnO99vJ$mRP|nZJ#TrYIYN2r-D@)Y2;&LQ( zTamjRQVaIu|0-tzBDXolfJ3_!I!;ma&pRGL$5=7qd$9;|IZ&*|z_y^{rm%q2?r73) zc<5ySk@IR-qfUqE46 zVMs>yICqg*Lj}LA7(45PADbNQdOWpom!cJ} zcm~HWXBeeD9@W@=hLg*bouT90^?U|uY=H$%QH~%R$Cr}%-If!R5$9T<&)g3#hR-Z~ zo+bSH@SQNMt+=cER93G^upr({yNs9MbLccUaDnL2@4u~n>&4?9Z`*aTT0g!-EF}r`@vH#y`tmvfJS{otbq&H!UIS}xQucGlk~`q zHvD5V%=4F+JXO(NfLtGJ7+`BXlzSI4IF|G@MlPo#b-egqqA*3y5+6Dg=2k#^+`_jB zF)Xw2XiCvkj%v){Wwg$j%f^`zEPCqK0zBYMWG;=4oa7Dd2Rxt5{`YjFGGNrC41Y`{t5 z_ZQ3@E;V+6A!a|g47k;E)zTpbV)UdrY8+qoxy>nvoo0_1SXy3UC4A3mg?-}|$$Ql3 zhUVLV_x?T&%lPq++#C?5z(1$KILDrg~` z3yTYJsY$i1bORauXuxM6I1GCLCl80n#<>e{jM!hE z$an+yjk8A#EK+>$hVz~dF~qz9F%UV*EkQZPnWpf66wn=K(KY%vTH>Q^gmr0@J}+Gy zUrrz1wmCOwp8he!OmTPQ4a2W#Yqqu?jXwq{HW@+WxNQ$l=`J1LW-J$*WUx6XoLnsD zhYa>OJiZ?=x)ktX z3M^AcD>Uh6Cu;cLizCGj(g1_Vg~+Mbf*H2K;BY)fLos2Q{_f)Y3-fG}OP7D>$~okl zMBxRr_AiuS1{XW+@qERFO_3eszRT`MbOQ!{2m^jofR0|ZEa5FLK*w-0gXQQwqdVG+ z{Kk!H{*FWQ91rMrLL1w39~t!OL}buOZhiEgJ?AFlXFFp6dwvAbRi9yrZH^?H7Dazj zKs6t18elG3^9@1tU4@SA`ui#yLJcmB9HMUxDGo);68_Evm7gUn5>P~4cEJxabUa@@ z{CBRXykxO)*6qMP|D1^Sn4-I*t%^+sxUvoA(n*f$zQ|w^zBNP-mYT|spkLEyl0(5x zw;-}Ljt7mlOy$?Fzj?tR3v=gUOh@xzDRL<~q?Xu^fA|?~jC6ypu^-%Hd9Y!B{j`M} zoChr!;2&MEmpL++8nw$A#=+yxwSXdgKPNz4-UB#zqi%7XkKQodz#eg0pzhreE7WB_ z{I0S%jBJ+yqxYwxFn+YdaXLa|YmA={4$9C!8W;^Dx8{efRd#^}=o)K`ydQ;~k>q`l z;pBzm_OQk24ZtgImRsQqM<4$~LqD@Qv>a8wF-XU`Jp?GiiS7?xsLLWq)bM{C@_&cI zaIzszJwFsE!*W|tn0o~GPX2C@^OO^=gEFIK$^m7B*ujV+gCc&tA=R=UKeY6eovx6< zY8z04zHp;uw?^}i?T#Ls*~TfX3!}aZNG+f_e`-N51L)WqCn3x6;vI(ppF-iKxGXF> z&c^8<>oVB9sdL_Qg3wfiYA2vwUjrh~=p0&30ZwIqGO|p6qgr4J9?(2R#%jwb1F5YP z7cb1^&cM_HG9p-E-36pt@W4OJa|J*Q?58#k(R&5a?=MJk;FluxPF!|{6^59m7(bfl zS%u@qKV)GB>+(W-j2}hzoHKS6jQYZ`>{IY+>Efk_6b*EcYT1wP5r0#-0Ff6yM{#_4 zmZE=b1OK}pJsTjk85iDgms+B>3GSn9zl3;S9bH<;*n}EB#hJ)?uz2D6mNhsz^xmDJ=pwb$Pi&GjyZJ5>^~a}H}*n=xiSBcfphF19~)!mB)PYVIRD%~ zzuf$u-*e9AoY^b3*(}z-TxrLbsxcPaZx-co^aiFf4|_Vy5%yC z@3q-bY!2_pWe&J_FE|13Yxty%(z0FwwN;T^aP-@-AtyWk1zg5er2f*;)# zp^1w<2?HC8KS2~ffBBh#9`QBg7q=p~1J~hmcmrl31w-H^56BPVJ@KaaDY-!2CP&F$ zvYrHBtvDlYr6AUdMpzP196N->q>|k%r>7#F(rRfUeELd@Pe6SRhp;=bCzCs* zWk;nknR2Pi(m^f5dQ} z$Z1KR)`K+PbLqm`x%zf0muVUr-WiK0Dq;<70t(VtPClGhatW3{Z z9h*s}74=Xt$uQfmXr(e~){ZTkB7@sE4q0=Xf&z-7CH<0|N<|cPB4bvrato-7R%U1P z$&4Dw<`1M5ZBm+TYtFTb5?rYC6LbF*;8aypLscg8miY>P`%<7U7o2&jPu zrbZRDILIiRkv9??vflbl9=l0@(a+=2)20<^3mXW$xKC9}{^zJU?AKpw(bvPhEPBEP{F@&V}d zx`l}m;Ntj6TuZ>U;4+pYunBo83hbN@v+WDlaedf=wwzg?n`^X&)YNjl=3P$6^KTh0 z!^>ur0oY!}1#vlaZ9Xn)HLyqtvQCe~FU01V#I?e!i1%D1@%CVicL zIEmqJxCej2ZTJ;_qL0-z_zb?I&(@ppI-G_t;3|9qAHg|zAKrzN^cZ)8VdF3kOFZYm zK4xl|@iJ$y0}4Ow1>07zp@MDYIfR4k)8%HCb1{dLnJ_bUW|lJ}Fk@pT!VJgEGLAzI zCpk>HTW5pt@9+!UhiM>W4!(rTWIwc%kLl}rp4@`>$XT+E+#_GZ8uBtsQo#;lH1lz6 z9qD5qRH=$@L6zv8K-HBs4&H}~@YVBuj{l%f%cqa=MAsn_3$lJMA^&N zu1{Ci13ZrA~4wMeDP=?!Mpe@9uNAv~4YITW_PxUg=3O z`_uRu93tY*I^n>nJL}c<-gi!x_#Y&<4pjwaJ?O@#h(bo%g z%M7AMs9_JsdT;}NEjiq+ZG|DiAsX1i2drQY;~3I~`v~1r{z;~1(aR3LS=;HdCB-N# zOSy7oCNVRwzIoYx|6#maO7gV-JpE`mlTJ)e27zlyit1qcWxmkVcg3asWHgn2noS4o z2$vMs?Zi~RoS!NbXLCW4>=46.4.0", "wheel"] +build-backend = "setuptools.build_meta" diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..9f64178 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,3 @@ +[metadata] +version = 0.5.0 +license_files = LICENSE \ No newline at end of file diff --git a/setup.py b/setup.py index 203ba58..c701aea 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='Shipwreck', version='0.1.3', - description='A library for handling Python errors and suggesting fixes', + description='A library for logging and handling Python errors and suggesting fixes', author='Gameplex Sfotware', author_email='info@gameplexsoftware.com', install_requires=[ diff --git a/src/shipwreck/__init__.py b/src/shipwreck/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/main.py b/src/shipwreck/errordetect.py similarity index 97% rename from main.py rename to src/shipwreck/errordetect.py index 6c8931e..0a11a38 100644 --- a/main.py +++ b/src/shipwreck/errordetect.py @@ -1,5 +1,5 @@ # ---------------------------------------------------------------------------- -# Shipwrek Copyright 2020-2023 by Gameplex Software and contributors +# ShipHelm Copyright 2020-2023 by Gameplex Software and contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,10 +14,6 @@ # limitations under the License. # ---------------------------------------------------------------------------- -import traceback -import sys -import re - class Shipwreck: def __init__(self): self.error_info = "" @@ -107,4 +103,4 @@ def show_popup(self): if self.suggested_fixes: print("\nSuggested fixes:\n") for fix in self.suggested_fixes: - print(f"- {fix}") + print(f"- {fix}") \ No newline at end of file diff --git a/src/shipwreck/logging.py b/src/shipwreck/logging.py new file mode 100644 index 0000000..061b93f --- /dev/null +++ b/src/shipwreck/logging.py @@ -0,0 +1,47 @@ +# ---------------------------------------------------------------------------- +# ShipHelm Copyright 2020-2023 by Gameplex Software and contributors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ---------------------------------------------------------------------------- + +import datetime + +class logging: + def __init__(self): + logging.log(logline="ShipWreck logging and error detection active! \n \n # ---------------------------------------------------------------------------- \n # ShipHelm Copyright 2020-2023 by Gameplex Software and contributors \n # \n # Licensed under the Apache License, Version 2.0 (the 'License'); \n # you may not use this file except in compliance with the License. \n # You may obtain a copy of the License at \n # \n # http://www.apache.org/licenses/LICENSE-2.0 \n # \n # Unless required by applicable law or agreed to in writing, software \n # distributed under the License is distributed on an 'AS IS' BASIS, \n # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n # See the License for the specific language governing permissions and \n # limitations under the License. \n # ----------------------------------------------------------------------------\n",type="n") + logging.log(logline="\n _________.__ .__ __ __ __ \n / _____/| |__ |__|______ / \ / \_______ ____ ____ | | __ \n \_____ \ | | \ | |\____ \\ \/\/ /\_ __ \_/ __ \_/ ___\ | |/ / \n / \| Y \| || |_> >\ / | | \/\ ___/\ \___ | < \n /_______ /|___| /|__|| __/ \__/\ / |__| \___ >\___ >|__|_ \ \n \/ \/ |__| \/ \/ \/ \/ \n ",type="n") + print("ShipWreck logging and error detection active! \n \n # ---------------------------------------------------------------------------- \n # ShipHelm Copyright 2020-2023 by Gameplex Software and contributors \n # \n # Licensed under the Apache License, Version 2.0 (the 'License'); \n # you may not use this file except in compliance with the License. \n # You may obtain a copy of the License at \n # \n # http://www.apache.org/licenses/LICENSE-2.0 \n # \n # Unless required by applicable law or agreed to in writing, software \n # distributed under the License is distributed on an 'AS IS' BASIS, \n # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n # See the License for the specific language governing permissions and \n # limitations under the License. \n # ----------------------------------------------------------------------------\n") + print("\n _________.__ .__ __ __ __ \n / _____/| |__ |__|______ / \ / \_______ ____ ____ | | __ \n \_____ \ | | \ | |\____ \\ \/\/ /\_ __ \_/ __ \_/ ___\ | |/ / \n / \| Y \| || |_> >\ / | | \/\ ___/\ \___ | < \n /_______ /|___| /|__|| __/ \__/\ / |__| \___ >\___ >|__|_ \ \n \/ \/ |__| \/ \/ \/ \/ \n ") + + + def log(self, logline, type): + with open('latest.log', 'a') as file: + logging = logline + "[" + datetime.strftime("%Y-%m-%d %H:%M:%S") + " " + if type == "w": + logline = "WARN]: " + logline + "\n" + elif type == "d": + logline = "DEBUG]: " + logline + "\n" + elif type == "e": + logline = "ERROR]: Oh mo! looks like you hit a ShipWreck, here is what we know: \n ---------[Begin Error]--------- \n" + logline + "\n ----------[End Error]---------- \n" + elif type == "n": + logline = logline + else: + logline = "INFO]: " + logline + "\n" + print(logline) + file.write(logline) + + def clearlog(self): + with open('latest.log') as file: + logline = "" + file.write(logline) + diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_module1.py b/tests/test_module1.py new file mode 100644 index 0000000..0b45a73 --- /dev/null +++ b/tests/test_module1.py @@ -0,0 +1,11 @@ +import unittest + +from shiphelm import helmdocker + + + + +class TestSimple(unittest.TestCase): + helmdocker.docker.__init__ +if __name__ == '__main__': + unittest.main()