makesure开源项目

我要开发同款
匿名用户2021年11月09日
45阅读
开发技术SHELL
所属分类终端/远程登录、应用工具
授权协议MIT License

作品详情

makesure

Simpletask/commandrunnerinspiredbymakewithdeclarativegoalsanddependencies.

Thesimplestwaytothinkofthistoolistohaveawaytohave"shortcuts"(akagoals)tosomepiecesofscripts.Thiswayallowstocallthemeasilywithouttheneedtocalllongshellone-linersinstead.

ExampleMakesurefile:

@goaldownloaded@reached_if[[-fcode.tar.gz]]wgethttps://domain/code.tar.gz@goalextracted@depends_ondownloadedtarxzfcode.tar.gz@goalbuilt@depends_onextractednpminstallnpmrunbuild@goaldeployed@depends_onbuiltscp-C-rbuild/*user@domain:~/www@goaldefault@depends_ondeployed

Nowtorunthewholebuildyoujustissue./makesurecommandinafolderwithMakesurefile(defaultgoalwillbecalled).

Youcanaswellcallsinglegoalexplicitly,example./makesurebuilt.

Alsopayattentionto@reached_ifdirective.Thisoneallowsskippinggoalifit'salreadysatisfied.Thisallowstospeedupsubsequentexecutions.

Bydefault,allscriptsinsidegoalsareexecutedwithbash.Ifyouwanttouseshjustadd@shellshdirectiveatstartoftheMakesurefile.

FeaturesZero-installVeryportableVerysimple,onlybareminimumoftrulyneededfeatures.Youdon’tneedtolearnawholenewprogramminglanguagetousethetool!Literallyit’sgoals+dependencies+handfulofdirectives+bash/shell.Muchsanerandsimplermakeanalog.Abunchofusefulbuilt-infacilities:timingthegoal'sexecution,listinggoalsinabuildfile,ameanstospeed-uprepeatedbuilds.Thesyntaxofabuildfileisalsoavalidbash/shell(thoughsemanticsisdifferent).ThiscantosomeextentbeinuseforeditinginIDE.Usage$./makesure-hmakesurever.0.9.13Usage:makesure[options...][-fbuildfile][goals...]-f,--filebuildfilesetbuildfiletouse(defaultMakesurefile)-l,--listlistallavailablenon-@privategoals-la,--list-alllistallavailablegoals-d,--resolvedlistresolveddependenciestoreachgivengoals-D"var=val",--define"var=val"override@definevalues-s,--silentsilentmode-onlyoutputwhatgoalsoutput-t,--timingdisplayexecutiontimesforgoalsandtotal-x,--tracingenabletracinginbash/shvia`set-x`-v,--versionprintversionandexit-h,--helpprinthelpandexit-U,--selfupdateupdatemakesuretolatestversionInstallation

Sincemakesureisatinyutilityrepresentedbyasinglefile,therecommendedinstallationstrategyistokeepitlocaltoaprojectwhereit'sused(thismeansincoderepository).Notonlythiseliminatestheneedforrepetitiveinstallationforeverydevonaproject,butalsoallowsusingseparatemakesureversionperprojectandupdateonlyasneeded.

wget"https://raw.githubusercontent.com/xonixx/makesure/main/makesure?token=$(date+%s)"-Omakesure&&\chmod+xmakesure&&echo"makesure$(./makesure-v)installed"Update

Updatesmakesureexecutabletolatestavailableversionin-place:

./makesure-UPrerequisitesOS

makesurewillrunonanyenvironmentwithPosixshellavailable.Testedandofficiallysupportedare:

LinuxMacOSWindows(viaGitBash)AWK

ThecoreofthistoolisimplementedinAWK.AlmostallmajorimplementationsofAWKwillwork.TestedandofficiallysupportedareGawk,BWK,mawk.ThismeansthatthedefaultAWKimplementationinyourOSwillwork.

ThetoolwillnotworkwithBusyboxawk.

ConceptsBuildfileisatextfilenamedMakesurefile.Buildfileconsistsofapreludeandasetofgoals.Buildfileusesdirectives.Preludeisapieceofashellscript(canbeempty)thatgoesbeforegoals.Thepurposeofpreludeisto@define(link)globalvariablesvisibletogoals.Preludeonlyrunsonce.Agoalisalabeledpieceofshell.Agoalcandeclaredependenciesonothergoals.Duringexecutioneachreferenceddependencywillrunonlyoncedespitethenumberofoccurrencesindependencytree.Dependencieswillruninproperorderaccordingtotheinferredtopologicalorder.Dependencyloopswillbereportedaserror.Goalbodiesareexecutedinseparateshellinvocations.Itmeans,youcan’teasilypassvariablesfromonegoaltoanother.Thisisdoneonpurposetoenforcedeclarativestyle.Bydefault,bothpreludeandgoalsarerunwithbash.Youcanchangetoshwith@shellshinprelude.Forconvenienceinallshellinvocations(prelude,goals,etc.)thecurrentdirectoryisautomaticallysettotheoneofMakesurefile.Typically,thisistherootoftheproject.Thisallowsusingrelativepathswithoutbotheringofthewaythebuildisrun.Goalcandeclare@reached_ifdirective(link).Thisallowsskippinggoalexecutionifit'salreadysatisfied.Directives@options

Onlyvalid:inprelude(meaningbeforeany@goaldeclaration).

Validoptions:timing,tracing,silent

@optionstiming

Willmeasureandlogeachgoalexecutiontime+totaltime.

ExampleMakesurefile:

@optionstiming@goala@depends_onbecho"Executinggoal'a'..."sleep1@goalbecho"Executinggoal'b'..."sleep2

Running:

$./makesureagoal'b'...Executinggoal'b'...goal'b'took2.003sgoal'a'...Executinggoal'a'...goal'a'took1.003stotaltime3.006s

SmallissueexistswiththisoptiononmacOS.DuetoBSD'sdatenotsupporting+%Nformattingoption,thedefaultprecisionoftimingsis1sec.Tomakeit1msprecise(ifthisisimportant)justinstallGawk(brewinstallgawk).InthiscaseGawkbuilt-ingettimeofdayfunctionwillbeused.

@optionstracing

Willtracetheexecutedshellscript.Thisactivatesset-xshelloptionunderthehood.

@optionssilent

Bydefaultmakesurelogsthegoalsbeingexecuted.Usethisoptionifthisisnotdesired(youonlyneedtheoutputofyourowncodeingoals).

@define

Onlyvalid:inprelude.

Usethisdirectivetodeclareglobalvariable(visibletoallgoals).Thevariablewillbedeclaredasenvironmentvariable(viaexport).

Example:

@defineA=hello@defineB="${A}world"

Variabledefinedwith@definecanbeoverriddenwithavariablepassedininvocationvia-Dparameter.

Overalltheprecedenceforvariablesresolutionis(higherprioritytop):

./makesure-DVAR=1@defineVAR=2inMakesurefileVAR=3./makesure@shell

Onlyvalid:inprelude.

Validoptions:bash(default),sh

Setstheshellinterpretertobeusedforexecutionofpreludeandgoals.

Example:

@shellsh@goal

Syntax#1:

@goalgoal_name[@private]

Definesagoal.@privatemodifierisoptional.Whengoalisprivate,itwon'tshowin./makesure-l.Tolistallgoalsincludingprivateuse./makesure-la.

Linesthatgoafterthisdeclarationline(butbeforenext@goaldeclarationline)willbetreatedasashellscriptforthebodyofthegoal.Example:

@goalhelloecho"Helloworld"

HavingtheaboveinMakesurefilewillproducenextoutputwhenranwith./makesurehello

helloworld

Indentationingoalbodyisoptional,unlikemake,sobelowisperfectlyvalid:

@goalhelloecho"Helloworld"

Invoking./makesurewithoutargumentswillattempttocallthegoalnameddefault:

@goaldefaultecho"I'mdefaultgoal"

Syntax#2:

@goal[goal_name]@glob<globpattern>[@private]

Thisoneiseasytoillustratewithanexample:

@goalprocess_file@glob*.txtecho$ITEM$INDEX$TOTAL

Isequivalenttodeclaringthreegoals

@goalprocess_file@a.txt@privateechoa.txt02@goalprocess_file@b.txt@privateechob.txt12@goalprocess_file@depends_onprocess_file@a.txt@depends_onprocess_file@b.txt

iff

$lsa.txtb.txt

Forconvenience,youcanomitnameincaseofglobgoal:

@goal@glob*.txtecho$ITEM$INDEX$TOTAL

asequivalentfor

@goala.txt@privateechoa.txt02@goalb.txt@privateechob.txt12@goal*.txt@depends_ona.txt@depends_onb.txt

Soessentiallyoneglobgoaldeclarationexpandstomultiplegoaldeclarationsbasedonfilespresentinprojectthatmatchtheglobpattern.Shellglobexpansionmechanismapplies.

Theusefulusecaseherewouldbetorepresentasetoftestfilesasasetofgoals.Theexamplecouldbefoundintheproject'sownbuildfile.

Whythismaybeuseful?Imagineinyournodejsapplicationyouhavetest1.js,test2.js,test3.js.NowyoucanusethisMakesurefile

@goal@globtest*.jsecho"runningtestfile$INDEXoutof$TOTAL..."node$ITEM

tobeabletoruneachtestindividually(./makesuretest2.jsforexample)andalltogether(./makesure'test*.js').

Incaseifyouneedtoglobthefileswithspacesintheirnames,pleasecheckthenamingrulessectionbelow.

@doc

Onlyvalid:inside@goal.

Providesadescriptionforagoal.

ExampleMakesurefile:

@goalbuild@docbuildstheprojectecho"Building..."@goaltest@docteststheprojectecho"Testing..."

Running./makesure-lwillshow

Availablegoals:build:buildstheprojecttest:teststheproject@depends_on

Onlyvalid:inside@goal.

Syntax:

@depends_ongoal1[goal2[goal3[...]]]

Declaresadependencyonothergoal.

ExampleMakesurefile:

@goalaechoa@goalb@depends_onaechob

Running./makesurebwillshow

goal'a'...agoal'b'...b

Youcandeclaremultipledependenciesforagoal:

@goalaechoa@goalb@depends_onaechob@goalcechoc@goald@depends_onbcechod

Running./makesuredwillshow

goal'a'...agoal'b'...bgoal'c'...cgoal'd'...d

Circulardependencywillcauseanerror:

@goala@depends_onb@goalb@depends_onc@goalc@depends_ona

Running./makesureawillshow

Thereisaloopingoaldependenciesviaa->c@reached_if

Onlyvalid:inside@goal.

Syntax:

@reached_if<condition>

Allowsskippinggoalexecutionifit'salreadysatisfied.Thisallowstospeedupsubsequentexecutions.Onlyonepergoalallowed.Thegoalwillbeconsideredfulfilled(andthuswillnotrun)ifconditionexecutedasashellscriptreturnsexitcode0.Anyconditionevaluationisdoneonlyonce.

ExampleMakesurefile:

@goalfile_created@reached_if[[-f./file.txt]]echo"Creatingfile..."echo"helloworld">./file.txt

Ifyourun./makesurefile_createdthefirsttime:

goal'file_created'...Creatingfile...

Ifyourun./makesurefile_createdthesecondtime:

goal'file_created'[alreadysatisfied].

Itisagoodpracticetonamegoalsthatdeclare@reached_ifinpasttense.

@lib

Syntax:

@lib[lib_name]

Helpswithcodereuse.Occasionallyyouneedtorunsimilarcodeinmultiplegoals.Themostobviousapproachwouldbetoplaceacodeintoshared.shandinvokeitinbothgoals.Thedownsideisthatnowyouneedanadditionalfile(s)andthebuildfileisnomoreself-contained.@libtotheresque!

Theusageissimple:

@liblib_namea(){echoHello$1}@goalhello_world@use_liblib_nameaWorld

Forsimplicitycanomitname:

@liba(){echoHello$1}@goalhello_world@use_libaWorld

Operationally@use_libisjustsubstitutedbycontentofacorresponding@lib'sbody,asiftheabovegoalisdeclaredlike:

@goalhello_worlda(){echoHello$1}aWorld@use_lib

Onlyvalid:inside@goal.

Onlysingle@use_libpergoalisallowed.

Namingrules

It'srecommendedthatyounameyourgoalsusingalphanumericchars+underscore.

However,it'spossibletonameagoalanywayyouwantprovidedthatyouapplyproperescaping:

@goal'namewithspaces'#allcharsbetween''haveliteralmeaning,sameasinshell,'itselfisnotallowedinit@goal$'namethatcontains\'singlequote'#ifyouneedtohave'inastring,usedollar-stringsandescapeit@goalusual_name

Now./makesure-lgives:

Availablegoals:'namewithspaces'$'namethatcontains\'singlequote'usual_name

Note,howgoalnamesarealreadyescapedinoutput.Thisistomakeiteasierforyoutocallitdirectly:

./makesure$'namethatcontains\'singlequote'

Samenamingrulesapplytootherdirectives(like@doc).

Usuallyyouwon'tneedthisescapingtricksoften,buttheycanbeespeciallyinusefor@globgoalsiftherelevantfileshavespacesinthem:

@goal@glob'filewithspaces*.txt'

Moreinfoonthistopiciscoveredintheissue.

DesignprinciplesConventionoverconfiguration.Minimalistic.Bareminimumoffeaturesthatcomposegoodwitheachother.Thereshouldbeonewaytodothething.OverallZenofPython.Thinkhardbeforeaddingnewfeature.Thinkofadamageitcouldcauseusedimproperly.Thinkofcognitivecomplexityitintroduces.Onlyaddafeaturegenericenoughtocoverlotsofusefulcasesinsteadofjustsomecornercases.Let'sbetterhavealistofrecipesforthelatter.Donotintroduceunjustifiedcomplexity.Usershouldnotbeforcedtolearnawholenewprogramminglanguagetoworkwithatool.Instead,thetoolisbasedonlimitedsetofsimpleconcepts,likegoals+dependencies+handfulofdirectives+familiarshelllanguage(bash/sh).Worseisbetter.Principleofleastsurprise.Testscoverageisamust.OmittedfeaturesGoalswithparameters,likeinjustWedeliberatelydon'tsupportthisfeature.Theideaisthatthebuildfileshouldbeself-contained,sohavealltheinformationtoruninit,noexternalparametersshouldberequired.Thisshouldbemucheasierforthefinalusertorunabuild.Theotherreasonisthattheideaofgoalparameterizationdoesn'tplaywellwithdependencies.Thetoolhoweverhaslimitedparameterizationcapabilitiesvia./makesure-DVAR=value.IncludesThisisaconsiderablecomplicationtothetool.Also,itmakesthebuildfilenotself-contained.Shellsotherthanbash/shLessportablebuild.Ifyouneedtouse,say,pythonforagoalbody,it'sunclearwhyyouevenneedmakesureatall.Besides,youalwayscanjustusepython-c"script".Customownprogramminglanguage,likemakehasWethinkthatthiswouldbeunjustifiedcomplexity.Webelievethatthepowerofshellisenough.parallelexecutionmakesureisataskrunner,notafull-fledgedbuildtool,likemake,ninjaorbazel.Soifyouneedone,justuseaproperbuildtoolofyourchoice.Developernotes

FindsomecontributorinstructionsinDEVELOPER.md.

Similartoolsjusthttps://github.com/casey/justjustisahandywaytosaveandrunproject-specificcommandsTaskfilehttps://github.com/adriancooney/TaskfileATaskfileisabash[...]scriptthatfollowsaspecificformat[...],sitsintherootofyourproject[...]andcontainsthetaskstobuildyourproject.Taskhttps://github.com/go-task/taskTaskisataskrunner/buildtoolthataimstobesimplerandeasiertousethan,forexample,GNUMake.hakuhttps://github.com/VladimirMarkelov/hakuAtask/commandrunnerinspiredby'make'guphttps://github.com/timbertson/gupGupisageneralpurpose,recursive,topdownsoftwarebuildsystem.redohttps://github.com/apenwarr/redoredo-arecursivebuildsystem.Smaller,easier,morepowerful,andmorereliablethanmake.Tuphttps://github.com/gittup/tupTupisafile-basedbuildsystemforLinux,OSX,andWindows.Pleasehttps://github.com/thought-machine/pleasePleaseisacross-languagebuildsystemwithanemphasisonhighperformance,extensibilityandreproducibility.
声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论