pax_global_header00006660000000000000000000000064136224752050014520gustar00rootroot0000000000000052 comment=2e9f37e04017ad212ae9497f1fd08f2045213913 GoTree-3.0.2/000077500000000000000000000000001362247520500127075ustar00rootroot00000000000000GoTree-3.0.2/.gitignore000066400000000000000000000042731362247520500147050ustar00rootroot00000000000000# Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders _obj _test # Architecture specific extensions/prefixes *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe *.test *.prof .idea/ GoTree.iml ### Linux template *~ # temporary files which can be created if a process still has a handle open of a deleted file .fuse_hidden* # KDE directory preferences .directory # Linux trash folder which might appear on any partition or disk .Trash-* ### Windows template # Windows image file caches Thumbs.db ehthumbs.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Windows Installer files *.cab *.msi *.msm *.msp # Windows shortcuts *.lnk ### JetBrains template # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff: .idea/workspace.xml .idea/tasks.xml .idea/dictionaries .idea/vcs.xml .idea/jsLibraryMappings.xml # Sensitive or high-churn files: .idea/dataSources.ids .idea/dataSources.xml .idea/dataSources.local.xml .idea/sqlDataSources.xml .idea/dynamic.xml .idea/uiDesigner.xml # Gradle: .idea/gradle.xml .idea/libraries # Mongo Explorer plugin: .idea/mongoSettings.xml ## File-based project format: *.iws ## Plugin-specific files: # IntelliJ /out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties ### Go template # Compiled Object files, Static and Dynamic libs (Shared Objects) # Folders # Architecture specific extensions/prefixes ### OSX template *.DS_Store .AppleDouble .LSOverride # Icon must end with two \r Icon # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk GoTree-3.0.2/.travis.yml000066400000000000000000000003131362247520500150150ustar00rootroot00000000000000language: go go_import_path: github.com/disiqueira/gotree git: depth: 1 env: - GO111MODULE=on - GO111MODULE=off go: [ 1.11.x, 1.12.x, 1.13.x ] os: [ linux, osx ] script: - go test -race -v ./... GoTree-3.0.2/LICENSE000066400000000000000000000020571362247520500137200ustar00rootroot00000000000000MIT License Copyright (c) 2017 Diego Siqueira Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. GoTree-3.0.2/README.md000066400000000000000000000066531362247520500142000ustar00rootroot00000000000000# ![GoTree](https://rawgit.com/DiSiqueira/GoTree/master/gotree-logo.png) # GoTree ![Language Badge](https://img.shields.io/badge/Language-Go-blue.svg) ![Go Report](https://goreportcard.com/badge/github.com/DiSiqueira/GoTree) ![License Badge](https://img.shields.io/badge/License-MIT-blue.svg) ![Status Badge](https://img.shields.io/badge/Status-Beta-brightgreen.svg) [![GoDoc](https://godoc.org/github.com/DiSiqueira/GoTree?status.svg)](https://godoc.org/github.com/DiSiqueira/GoTree) [![Build Status](https://travis-ci.org/DiSiqueira/GoTree.svg?branch=master)](https://travis-ci.org/DiSiqueira/GoTree) Simple Go module to print tree structures in terminal. Heavily inpired by [The Tree Command for Linux][treecommand] The GoTree's goal is to be a simple tool providing a stupidly easy-to-use and fast way to print recursive structures. [treecommand]: http://mama.indstate.edu/users/ice/tree/ ## Project Status GoTree is on beta. Pull Requests [are welcome](https://github.com/DiSiqueira/GoTree#social-coding) ![](http://image.prntscr.com/image/2a0dbf0777454446b8083fb6a0dc51fe.png) ## Features - Very simple and fast code - Intuitive names - Easy to extend - Uses only native libs - STUPIDLY [EASY TO USE](https://github.com/DiSiqueira/GoTree#usage) ## Installation ### Go Get ```bash $ go get github.com/disiqueira/gotree ``` ## Usage ### Simple create, populate and print example ![](http://image.prntscr.com/image/dd2fe3737e6543f7b21941a6953598c2.png) ```golang package main import ( "fmt" "github.com/disiqueira/gotree" ) func main() { artist := gotree.New("Pantera") album := artist.Add("Far Beyond Driven") album.Add("5 minutes Alone") fmt.Println(artist.Print()) } ``` ## Contributing ### Bug Reports & Feature Requests Please use the [issue tracker](https://github.com/DiSiqueira/GoTree/issues) to report any bugs or file feature requests. ### Developing PRs are welcome. To begin developing, do this: ```bash $ git clone --recursive git@github.com:DiSiqueira/GoTree.git $ cd GoTree/ ``` ## Social Coding 1. Create an issue to discuss about your idea 2. [Fork it] (https://github.com/DiSiqueira/GoTree/fork) 3. Create your feature branch (`git checkout -b my-new-feature`) 4. Commit your changes (`git commit -am 'Add some feature'`) 5. Push to the branch (`git push origin my-new-feature`) 6. Create a new Pull Request 7. Profit! :white_check_mark: ## License The MIT License (MIT) Copyright (c) 2013-2018 Diego Siqueira Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. GoTree-3.0.2/_config.yml000066400000000000000000000000311362247520500150300ustar00rootroot00000000000000theme: jekyll-theme-slateGoTree-3.0.2/go.mod000066400000000000000000000000601362247520500140110ustar00rootroot00000000000000module github.com/disiqueira/gotree/v3 go 1.13 GoTree-3.0.2/gotree-logo.png000066400000000000000000000571671362247520500156600ustar00rootroot00000000000000PNG  IHDRf}; iCCPICC Profile8U]hU>sg#$Sl4t? % V46nI6"dΘ83OEP|1Ŀ (>/ % (>P苦;3ie|{g蹪X-2s=+WQ+]L6O w[C{_F qb Uvz?Zb1@/zcs>~if,ӈUSjF 1_Mjbuݠpamhmçϙ>a\+5%QKFkm}ۖ?ޚD\!~6,-7SثŜvķ5Z;[rmS5{yDyH}r9|-ăFAJjI.[/]mK 7KRDrYQO-Q||6 (0 MXd(@h2_f<:”_δ*d>e\c?~,7?& ك^2Iq2"y@g|UP`o@IDATxUH[zM&MQ v} {bC,<{ņ "R^W/\lnn-[ŝ=礝$Lf&%LRJI&[[dcSq %nݪlb~;v[C~M͞=[m߾](Q _v %Wuʕ+g@q (~zäFq @l tV1.2j%jޜ?Ԋˢ^bZjeTX5UZjQjQM5W5S2*`ZA]/]~FYj97UA1H 4ӈګުvA|M[ArنӧNROYrYl4{nZ UAqC[ARh;ȥ_}fN-BKڠQcբM[uebIhEAOY~AŤXX#946lP~~[5 oXeUR5jVj Y~J2U24RDPLEUjՆ%&iA-OfkU2ez)HϏJX?כ n眦qڸ%'B"D hS԰+~(ƀ[Q˖D1}?fS׎-[e5kk&ՏP+7NReKWU*t.k&U92k[2꬞wMRUUVjT]U*=UUtU)u:iD_qZq)QCcx_=ӆs;x]+WF~牊vI$ K9!73WݫMJ҄kz8Iժ}`?Lz Qq Ǽ*|#gcejH":$+Kv)S{A5Q~:r%7D)1a[9CsKD<\T-܍67vîZ{n5TDGm޺ѐlWV=S8@UDO6J{`%~Aq=[V4 jUvAb]7UrՑ?Qg؆"QSߎYʷrؑ1syߚUQ1/\<3Nd{|D@o%-u9&pǃQGT%.3CxKE3WYR*{:fp0/qu|_w=ࠨ,X>t-joEhwsMrH(~|5z޲DA V+M )wo-}Oy&}ȏ3ܯiE>`rZ_rv?5}sjێJ=U}ق0f];{ H^_u9roLեGcTNjUmX.xǯVeJV- ;7ioaUb*7QU*TW3OT+QmuQK7QMfz߄w_խ=*M2=]~ST%/}/UjUs%r2ZWg mOf!f`ìppZW5yٽxV 7Mȳ0x!@|PmH=qDUwmރ-wx)̆O#{Szsuw7v={A>ov(ךhڰz'rTXG5#Qsz` ȫn*VI 'wWVE Ah0fI(fVť{,\7BA@&|l/M^y*H#7HU/1>)*ثB#5+*2%y\Y AE'A0r;Sی>iXEv+Y ͖#EL^V Į}]zH#=Y7 Gs}s$A4YlP0BmN(xzq>\{^5zx{WJtXAO bJ9ȇejsWջ(6]]mG] )S0YFNYICTfW9ؼ\KuU~A1Rr{Gnч.LWGM@f o:65@*:JͫGc#|eՅ?r N]-|Cd6|A 357l(#c&Υɍ4 C6ģc#n"$? + ,9vn(rP̸ m_6mX vix  3EPC%ZI p$i$ m鐑  ce Ұ2y=u}O~I {o&9lޱH9\!ed/~Ex=42brAx&D=mO;lu5sŋQ>`+Tז~{#o~/Pr $w8ȄzIfqUKJ4f;}saVӸ 5nb<«rxUfF[?+n)SGAGe*J @}pYEx&iSrtFѼql:Ÿّ*ʕ`h}%k6>/@ Ĥ[EFܗ5j֊Bv69 f"i ß%/jqF;#&$JX^qVj9`{?)gBϽsF 9bM vW Ę/ߦM13<9o /.xv"v޸HڨFK [6Tݏq#ȁftQg0$k.]w5r^t B,YhYMze3$z8k5Ԣ:0]mV>L <JiX|)O; iVq3G(\;4n n]e)% $o'{{_zt$ ⅧR=KN{7}{h" JW^AK"1u@4bTIʊ #;<3Hth3hkQ% ؄ Bmׂ\%%SȇYm%e]=!09!؞fC!Rҷ #-Tcl9i,tjL\neHaj։lI8WH=[1%brgt> )/i{F CM].y[t<[ĈBwֲж>`')i{7dtUze*0S<";M'e祱 |v3)AΈKm't~^J:iIuo5j <R{|=(dIՕhqrWmYQfN=^[ @D5v;Ex$T;_&"ƃ0h} {f{:oUO><@Wj뽎:t233&=pJ̦vsӍF %!ol{֞EΌwԟD+7`ERM{~ψ%39%z $ABUC$wDg /Rhb\5a9jTlw<؟L&4Bq:l2,O6_3b6Mf2?* _?::iʔѰ*S_\3l4I@j{Ee!Gdѭ S*#}_(9NajR=]v'z:ŊTߣQΟRBl:/JpW *,bdIOY=97IIXs'2AhfvjӲֵ.,W__ܩWn wUPxqxl9*8r?z,H\^~oQQGI꺭v,مμ3(4 3u!/>UN؃[G$S0æ1L인Uɑ/^M[皫n3y&uV s/HmKMmH9wKdb& .00<p~vq*!J !|.SrѓnƩW={&B.p& $!}xRXi$/bcjj[ n5"X@E[4aoxޣ9쁼I9hAHm&-})uJtH[qeI  eWmNx"BADy~AG?~#QWH3z GRUtH+C2"٧G@@}`t pPi\8*$Ç{ޭjg/Q""$ض^e%9X9S`{vc%UXL*YDtڡJ۬%Αsl;<=6L֍ m+AL y"P#+b3I9&:xHp#R썛bRdV=H;DP/twe`lk3.po:{94gX^IxyA%bbqZ!aIrd+*c3nxN;PB#l(ـ^GwHи-Ό rT36-o#!Qo`;®M~.AmRV{rQpo!/[҃$gj9i ZDОΗ*+nٸʔOi]AX"9mʈ.r\ppsmEӲra[ {CQ.L/lC$;lt $revՓ;ۋ~Z ~x4qgtKt=+;iE_~FaΉ\*a;Oر}Zdvde/}RH9\~'lYœ琨#iXa]drdt:>Eэ98L_m D҉KU$BM5]lkOcaD{oz 1 GNN:% ˖-T:P 1b﵆)4&]Cѓ7wٰ$MH_e5oS&}1xfvph7{~_\tg -, x,ec &{䊖2ANF&aW"c"61AC԰5=+v^<o{[+vD4(AHnPHyC;[^fKͰ؋"MTV*y|;{<6KX29,0|;z!lh^; AܤmF)pM\q :9YǼ3 va1KI"Oį;b/ ̨& O 7;*Q"@ưU/{A4cg%*L4i01 @4;SZ oׇ^+AFT%g>x&zھh#mNoe!ϛkN~0gF/ 1_q_If qG̚.0s'$bB~fw*ΰO{P c._{dT hh1+!B{g_!僵0Qou^Q, fF&DV<ɡkH*E62Y6T噫o qawc} K.VA" !ϑر݋@ 0?M"1Cd9Qbl<$3&=>q' {lrf#NsAiXqBpbZ|?ILR.WP*j H6pJChpߕqxiHc4 xB0D1d#o YrBA*Std |A HU)~'@01h㜚cAZ5Ґ/tcSFXA\iSFX {W^ӂ .䓎tg `:%+TF =۳ĊCBn>Rrl14]\8o"Ab*Ĭ9**;̀˨,d5Rӑ5+64&w}kLcvXAާA̛ 7 #v֑vfI#^8ilt_`r^ϺQ ={>`yfDH2sqд{drO;'֭o#u3J|e8 Ix~f^-ފRt3m]nVTbjW<'Iݧ'j|$3| J}O~a&l13p8.&0!>q"RY2OHܞV VEtO;51 "RJҸ 2JG? Xݚ[ ?Q+@8aeԷ8gIGevPت۬s}~nH.`6}EV _At68QVF X n첉HZDB>GE4<'[ (-d+ݟ綠'zCR_ɳ\4VP'0\qlpt;6< zO"+U $kj <iN=RCv: i+ $jl0` h)&Y|+Sӑ|G]Bۭc m -i|3kTwCnWoۺ9=*:ka>j}>jUw켟Qq:+HSĎvFߍW,:ɇjH{yVu]ԕ ߸6F:nE#eԩ]]})Iﻺ)iF:xnE PwDRMd*eZ(0W˿/M;8~BH[ArsĀ (0LBVV6+Gx?v3ˊx$-A@ӱaR}%; x4o岥Qv~? ;KEs$QjE3l@}Q9 R=Ԍ%y$UKH/jW_tW̫DyW"JZR~HK PieJVN9HTϺuTC!d^ʔP:7W?k P>x%>f$N"1.)HZ,&/}X#[y_e  jѺ,Y4H<.$UB,4VMJY-՞5OWJ#Zv C8(lZAL4>FPu?H~2Ujs}Dk3ԡmuF]>yPS5-}˖&9kyk>1y*kuF Y׆8AOH$_ ||vHkDEžوc#J'idjڳ{UՊԬS -Ws;KT?pV>S;|(rM4CȾA*})/%kq$7ImZR/j/~ I5cxJ-\7 zhbg]_F=xzQrvً[&/yv9>͕-2ж6{eo$71e}#2I{ORI]ʏ]TDcA!-;}{x $B[v%͋Cq!O0R0Y[/jr&Ҫ13BcP*=M+q6i ?zvFjr0dᘷbx8_Rsmt $qt> 0|#+i`N50@kJ2Q,2jxEcḱp2̛(tAځEKûi+5? rYID˗MT ~ae0@ AP܃tg4_'!0ROF#Pd% @tvߣC0S oۅDR(;{Dr!6|M켈G1e "e # @XtPlt%#Вx~UFmEݫ OxdJI RAC(^S~,{/vJ4]\fp_DC^PoxaTZϾ7z~Uꂞ (~^!ϣ8ϐ6$B ]2)J"qˌJ'zv<䨴.^5=@6y-pAE[mf#|b}0aUbЃbp͛¼Ԏp &D ]AI6 hmC1@jTofQIFN> {t)^tIc+q6'! 3VgERnzar{=)ޔ۸`]"PqvQUy8RG4,'I; =mէšA;UXne2>;.%d @N3"Ɗ"Asq" d6} ja泾O;W 8%O ipH+ĿMxs;R<ҫ#[}9 `]^u&Qج%Bb}2GU!udK yA[~T1}w^mV O}ʍ噲^ԛ}NrQ%9~Jaށ4|¾R uVqxۀxjqGll۷P P'rX?;٠nzQ$MLl>=}fóO?tlpߊ&Yҡ~ͷ%e“Q 3zH\Y>Z (l:xu&t$<[u`6!O84wޯܰ([}.|=E(dDj=@6$鯏aWzh 򡫦Nz x69v瘄MZ:Kp3l|AyKzFZe>Œ Y3Og@D+ZN5ħVc`piN`DpH *Y9HYh§:lgěäPvya \fm;wH$dC:@CB[wECwqߞrErO1Ɨmd󅩕@؀#5ɭov`$^xdX!S)>mX Wr;"{j;_68}OHʤH;^rs;A}^X|e jyݗ)RNڒcD5)q-ĝ#\m$*q|k0[ZC^sqg ΛY9+gV%{"LOo-+XN Ϗ[Ia=ᦲR'L8ehٍNJ;|35jxɷNsK_a T,D]F|ɾ\(y:y{?)P=C#G^ק2nvxd6'-yD{Ԏ,;#44[Ase]XaxO 2k!rXQpID+-c<1HxmC8{;6KZէJL5,-M9s@~~Nr<Wh[JTř&0!3{Px%Y1&/?0)A|@=l$ !;v8 8 ͒%/062i{)ecG*>mf%n(uv>(\y= 5c8O^}$>uʣ]tQ</|g=ȹAe=v'e@8=t8/l>|8Rxt1 0`a a[fh -;ƐU>HdG;BԇHEng_1Ȼ\3v?-`tV&n3};tg_,?7&*?!iAq9c3 8ppOe`٤AiC۝6[Y+9#Y8c'񾫫3xr%*G<`CQV1I /"/㌶OCdw|?N!9b5wڹx\ yVemwz529+6,0DL49)"ͮo| L %*n]✞E8K:5O&>ttb%1̚ RȻα$\!;@Ni!4PtFF|/i`z$v13o[;zE>!@bC^TYW3W3h=!̪rd[NXrsZV\6XE| Mث7.634 +&5lofa9bkAzl(W4$̽؇ʠkxȁϷo lwud_!J%> njK}zglXn*.#d /ӂ TSa]HYHt qƧĻQG |3cdIH|ʀm:zp@VWVfPVB'$Q/VzY A[X$IbS.$#L(/+Aqn8 V01?ӆ F˳+΀s;>|2#dMA6,ےR٘{=PjvDǛ0?m'dvrx|/% DՆ =g_0`m~`!Ih~)hs(Qx rdLH<1d}Zx*F;r2k}tiAfw]xf(֌EN)k9G0u{1hUܨAl)+ѕYdHʒ#A*wd3OstZN*kUv=s_q^?ʠ87Ln\zp̸6v`Y|۷,lTѦ46|Os>S3w LAW CZc(ѫϱf6ER" BnA={ 8ȥ Q :J<*X!9ZS@z}# @2!.htic^Ib E@q( Bf%b@ftّggS휋߁ɷ '%] ~IO.iB}ڡzNDb$'{RQsĐò}sVF[L91(!|mʁJI5BҊ $9ɒYl|M֧'vmcć1PWm18E఑$Arb̠Qvb5 [=c'2"3eيKטgK C? H}Zނ 0bAU@>8Y2 y䰡1!u4v J5i]Ξe,VPAv͍sk%7Re"pE;./M630jh'B8fi'Mx%ռI=bLV!j`b`qDxւ-\# zͥDHxe#Cy<vj{‚ygb 0e&M&@uO\t8q}ubuc]90HLH{#i#UD~l3PAG]]O/[u4xAؘﰴ fQwLR"r$yɇbȭD 9G "<4U!mUSܩKo$Ȫ٨<<>_x{:vixOSjzM}G:ƿiSc墐V2UR5i(5|sc^ k{ײ2+1$[ߴ#p}>t>/e$^YňasM h"1ko@VZUs[Birp:ۈhѮݶ}EhpL"to9οa$so]}f;u_(F+?% َ 0T_X2*b,WH"s `;M~ߏ}^CQG(fea#5ީ6U\0㍦OP˕}- csЮG 3`"1 1LhTȓJ>hktW;f$Z" PB-װQ{{@D_Wx A؆U N]` uŤ8`(ѪS(D$}.Q9v&]>YV7M3zDI{襝Ϙ_@teޗ&mŝ6x{C@a-5X-D ]Ӻrse2I9h^< 9iIDATc#R~7r Adq+)pZW}zg&g;7Y8WDז_~Q'f-$i8VQKexM bRYq ؇O8?eKbq̈́ՃzUp{6}w8L`M^v_L6M@eP Zhxy XSkS> c'; |]@ 9/Wg)V*ޑ 8Ȗd  zUC@Qxa@Iu|AZ9!?ursH6+gylVgO 2{4!HǛ_=zC#M3e I g=:FL  F5Nj 'CTHe:e(Fޅ(U;Ի! 9v~|=;n^yX9FVH|A\!Ӷy}23i> "}-VNEÀ_*m "΅S_v~㕌(:i,|qE%V5V*X${.캞qϬBjIxr$]n1^qew<>;Rז T(c˔d[1b*H|njI|^J&O^TX])|j'o4f @ҠwゐZn<柲-q^E0ܖWA6~Kfwe 6Z4W!ayo)gRrZ<|}Ng"dk(H0d'd*b"!iSr] \;ߞU΍t}jF! . v#,9ng&&}gRf&}L_g2d$9y>B$c\!7@6mFX .B+q`_te$H406N7y@p  Ʊoo3Qj%k"CWv2aWLO߸'hI;ۢ 4 gfkv&䵃D'IYîo#0/&$SMg,lLL9L;vxh1텅$SM>bɖtzЇydN" T싮6@z(V%+"+ L]EA8jaH=< _mDE}I9転E Ah`f>r+]/Φ *B[1 }UT9yI$gOFSVh30蚶fb}D_e(u;離V~8[}—,^/o|~)[0N9p&/'uLGF~Ah5!?Qdn<$ ߏQʹZ'-ZU6_mݪ=./ȇPk˰@LVUb;(ޣvb?ȷR'q^uL*G.p&BLVTH*MDEQZEzb0~om>Fm۶U+3\mvwijoӂwfNTN;;cۗ< -۴QdvDZ|g&A1W< ΚcpUS"!?$G*VR+V )Q!K' zzнjF0 {owD1]=͈X%o^re\2/9&.]L(}GC^KNQ]rfFdN"m~! IΖJ z@IdU lCdG ͠}Eo61Co~Aw jG:YĠNӀ}uU1"TU$( ~}UOHYMK Ş͈Sa7B;~W!thd9cTCLzUac ]Z /)<9#]YBn7 4d=p6";Z;r$Z=wdεdoX5 Evy=aU" a." Xft24t<{Sm N4a\BIbp[$\ VQ+r*T'&Rݪ7mT?o;^ňuQ}bOL=D5h⩗y9Juwse^m F -Xfp/ ufGc"|`CUn嫊MfujW )"R]1mjAeF;yIk ,i1i o\V'ƾEV{m;OAArvQ9!Ő"\TqvȪ+ i@5kVmک)Z&ZE5T{(F0Ȳ˖(NڴiZ0ov}$N' *ZVz _ob}@tO̐(F jdf #HfKq2$C:R\ ibɐ(FfnX?6n׮Qko_FY҆aqNsn۶mjZڪt2ݻb2AV,]>=5o՚Չa3*hu@Mt7CG(QDqߩ1n꒥t2t2ۖ-[M7jkX(O{i#jSմ)mQa\^4]̯\!Gv+BDQm_K(BKH u$}+ꃷ_hvTcN$Q$ƒE_|6^L防B̲|UUWeEe^Ip V tj+uf9@m6*Ő(4LG}ō.VU|`ehԤxꇯR=M9X喼-^/[7_ÖA]v=|VQj۲e*UsSqToߦ.<(g`]yoXv>&taL \daJ[4PVf ! aGN=`wvD d 瘯>U? }e})j0D\nZbwAS`>_JcCr5βX|n5T}V ?3%w.B _6yF $' hBԇs Lﵔ7aI$H3{n>-=7\~4{lOGzW`LUWWժP[`eft׫tsL:jsreK@ NZA*U*U?om+z;M׫lw褯's'_d)=_Qյ:> ˖{Bk8/M$ uR|H|(WclrU7FwjL,b}kSϾPǟS~33ݡOF dS/\~Qae+nw|:(*qvczs-YyWb!#*W)AM˖-.&21CV":ib༻d`UDˮS~W^걏!oZɴ1\y2ɬ8Q%CZdW#bkf, 9֯* ۯD͟CN5n^.{f?E՝7\|/Qҙ1~E=QgnbrzWKa@d'E+ZjeXǕUGG%z.eψ*%yDZj91[=hV,wѢMBWV{ÿLQQU^Qv6Y}5"F\۶c\W]vZzMLx#cZ2A B+W, ޭLO1 kϵ) J3~KV\ňc*KvϿnT^lRu5P>ukbn@z+Ta_ry 7 ct#p7lԕ."¬z^A:d=>Xߴ4B+Y^N[U|&/{CVTʬm|ͦ,eI߲B A갏ӏ``*4Jen_sti|M;lO~7pm;3Sa&7_z4aj1rޝcp# 2sC*+($A1QJftFoob֨lLJƘ-SiݠQH\zuTڱ0# 8J~>[>y}{^GiV=E&ꔳ.Q$OMV*UuF}:QƐOe- KEePKOJ9fdWXAUQKH <䋆gƋzOBߜb=}z KDZgJVf*ihS7ȟW?Ycb[eКŹܕu)1yo< )%Mw Z{ɀ[~<=3v;a*Y@O{y#]soͧOmѿWvM4C5s j# Q3 N"+]7_Q{ z*fVyi!FQO?|V=O-@p8 V3&iY~*QYtdo$Ӂ  h@}˕ވ>=, $ ۬ ̲5ӞnH+q==Bq> LM/{Vw# HCy5JzrѕgoOf%]QOB&~8fG#Ɂwyrm֌m?fNW/;J~]4oK𠮟nH;^ 3S'd%,[rh+?.U?6,kws6(Jzg?UXdq _ Z6ÐU[) ?($ l?f<7_{ /W!# AX>g|jqݠ~v08~eF ޥ?G`zwdcMZ dyb(>`6N Ѱvhw9ǼS/fɜٸtC0}OK(lr1 `ghƯS BAP:X59ȽLz_ۤuc`=s2q뢫^Bd>sV/<[U=;Ɯ^LF. zy#oI;sDLi?zmj TH5}#Tߎ1˩'sHC(- O>xSبy7 i{;S՞%Ib\~NgöZK0=!^2cՂs+Gr@*H+.¤ř[ -P ilW(Fg5Nc #HUEJn(v_zik ,%Mۋ_T%k0KFd^@[ RkPa>iTIENDB`GoTree-3.0.2/gotree.go000066400000000000000000000043151362247520500145260ustar00rootroot00000000000000// Package gotree create and print tree. package gotree import ( "strings" ) const ( newLine = "\n" emptySpace = " " middleItem = "├── " continueItem = "│ " lastItem = "└── " ) type ( tree struct { text string items []Tree } // Tree is tree interface Tree interface { Add(text string) Tree AddTree(tree Tree) Items() []Tree Text() string Print() string } printer struct { } // Printer is printer interface Printer interface { Print(Tree) string } ) //New returns a new GoTree.Tree func New(text string) Tree { return &tree{ text: text, items: []Tree{}, } } //Add adds a node to the tree func (t *tree) Add(text string) Tree { n := New(text) t.items = append(t.items, n) return n } //AddTree adds a tree as an item func (t *tree) AddTree(tree Tree) { t.items = append(t.items, tree) } //Text returns the node's value func (t *tree) Text() string { return t.text } //Items returns all items in the tree func (t *tree) Items() []Tree { return t.items } //Print returns an visual representation of the tree func (t *tree) Print() string { return newPrinter().Print(t) } func newPrinter() Printer { return &printer{} } //Print prints a tree to a string func (p *printer) Print(t Tree) string { return t.Text() + newLine + p.printItems(t.Items(), []bool{}) } func (p *printer) printText(text string, spaces []bool, last bool) string { var result string for _, space := range spaces { if space { result += emptySpace } else { result += continueItem } } indicator := middleItem if last { indicator = lastItem } var out string lines := strings.Split(text, "\n") for i := range lines { text := lines[i] if i == 0 { out += result + indicator + text + newLine continue } if last { indicator = emptySpace } else { indicator = continueItem } out += result + indicator + text + newLine } return out } func (p *printer) printItems(t []Tree, spaces []bool) string { var result string for i, f := range t { last := i == len(t)-1 result += p.printText(f.Text(), spaces, last) if len(f.Items()) > 0 { spacesChild := append(spaces, last) result += p.printItems(f.Items(), spacesChild) } } return result } GoTree-3.0.2/gotree_test.go000066400000000000000000000142161362247520500155660ustar00rootroot00000000000000package gotree import ( "fmt" "reflect" "testing" ) func ExampleTree() { artist := New("Pantera") album := artist.Add("Far Beyond Driven\nsee https://en.wikipedia.org/wiki/Pantera\n(1994)") five := album.Add("5 minutes Alone") five.Add("song by American\ngroove metal") album.Add("I’m Broken") album.Add("Good Friends and a Bottle of Pills") artist.Add("Power Metal\n(1988)") artist.Add("Cowboys from Hell\n(1990)") fmt.Println(artist.Print()) // Output: // Pantera // ├── Far Beyond Driven // │ see https://en.wikipedia.org/wiki/Pantera // │ (1994) // │ ├── 5 minutes Alone // │ │ └── song by American // │ │ groove metal // │ ├── I’m Broken // │ └── Good Friends and a Bottle of Pills // ├── Power Metal // │ (1988) // └── Cowboys from Hell // (1990) } func TestNew(t *testing.T) { type args struct { text string } tests := []struct { name string args args want Tree }{ { name: "Create new Tree", args: args{ text: "new tree", }, want: &tree{ text: "new tree", items: []Tree{}, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := New(tt.args.text); !reflect.DeepEqual(got, tt.want) { t.Errorf("New() = %v, want %v", got, tt.want) } }) } } func Test_tree_Add(t *testing.T) { type fields struct { text string items []Tree } type args struct { text string } tests := []struct { name string fields fields args args want Tree parentCount int }{ { name: "Adding a new item into an empty tree", args: args{ text: "child item", }, fields: fields{ items: []Tree{}, }, want: &tree{ text: "child item", items: []Tree{}, }, parentCount: 1, }, { name: "Adding a new item into a full tree", args: args{ text: "fourth item", }, fields: fields{ items: []Tree{ New("test"), New("test2"), New("test3"), }, }, want: &tree{ text: "fourth item", items: []Tree{}, }, parentCount: 4, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tree := &tree{ text: tt.fields.text, items: tt.fields.items, } got := tree.Add(tt.args.text) if !reflect.DeepEqual(got, tt.want) { t.Errorf("tree.Add() = %v, want %v", got, tt.want) } if tt.parentCount != len(tree.Items()) { t.Errorf("tree total items = %v, want %v", got, tt.want) } }) } } func Test_tree_AddTree(t *testing.T) { type fields struct { text string items []Tree } type args struct { tree Tree } tests := []struct { name string fields fields args args itemCount int }{ { name: "Adding a new item into an empty tree", args: args{ tree: New("child item"), }, fields: fields{ items: []Tree{}, }, itemCount: 1, }, { name: "Adding a new item into a full tree", args: args{ tree: New("fourth item"), }, fields: fields{ items: []Tree{ New("test"), New("test2"), New("test3"), }, }, itemCount: 4, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tree := &tree{ text: tt.fields.text, items: tt.fields.items, } tree.AddTree(tt.args.tree) }) } } func Test_tree_Text(t *testing.T) { type fields struct { text string items []Tree } tests := []struct { name string fields fields want string }{ { name: "Return the correct value", fields: fields{ text: "item", }, want: "item", }, { name: "Return the correct value while empty", fields: fields{ text: "", }, want: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tree := &tree{ text: tt.fields.text, items: tt.fields.items, } if got := tree.Text(); got != tt.want { t.Errorf("tree.Text() = %v, want %v", got, tt.want) } }) } } func Test_tree_Items(t *testing.T) { type fields struct { text string items []Tree } tests := []struct { name string fields fields want []Tree }{ { name: "Return empty if there is no items under the tree", fields: fields{ text: "top level item", items: []Tree{}, }, want: []Tree{}, }, { name: "Return all items under the tree", fields: fields{ text: "top level item", items: []Tree{ New("first child"), New("second child"), }, }, want: []Tree{ New("first child"), New("second child"), }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tree := &tree{ text: tt.fields.text, items: tt.fields.items, } if got := tree.Items(); !reflect.DeepEqual(got, tt.want) { t.Errorf("tree.Items() = %v, want %v", got, tt.want) } }) } } func Test_tree_Print(t *testing.T) { threeLevelTree := New("First Level") threeLevelTree.Add("Second level").Add("Third Level") complexTree := New("Daft Punk") ram := complexTree.Add("Random Access Memories") complexTree.Add("Humam After All") alive := complexTree.Add("Alive 2007") ram.Add("Give Life Back to Music") ram.Add("Giorgio by Moroder") ram.Add("Within") alive.Add("Touch It/Technologic") alive.Add("Face to Face/Too Long") type fields struct { tree Tree } tests := []struct { name string fields fields want string }{ { name: "Print a single item tree", fields: fields{ tree: New("single item"), }, want: `single item `, }, { name: "Print a three level tree", fields: fields{ tree: threeLevelTree, }, want: `First Level └── Second level └── Third Level `, }, { name: "Print a three level tree", fields: fields{ tree: complexTree, }, want: `Daft Punk ├── Random Access Memories │ ├── Give Life Back to Music │ ├── Giorgio by Moroder │ └── Within ├── Humam After All └── Alive 2007 ├── Touch It/Technologic └── Face to Face/Too Long `, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := tt.fields.tree.Print(); got != tt.want { t.Errorf("tree.Print() = %#v, want %#v", got, tt.want) } }) } }