🌳 tree (sharpshooter)
![Python package](https://github.com/byteface/sharpshooter/actions/workflows/python-package.yml/badge.svg?branch=master)
Shorthand templates for creating (or destroying) file-systems.
tree could be written for any language.
![](https://github.com/byteface/sharpshooter/raw/master/tty.gif?raw=true)
install
python3 -m pip install sharpshooter --upgrade
python3 -m pip install sharpshooter[jinja2]
CLI quick start
cd /path/to/some/folder
sharpshooter -c hello
sharpshooter -t hello.tree
sharpshooter -f hello.tree
sharpshooter --mock
intro
To create a plain empty file just type a word i.e.
file
to create or access a dir use a slash /
/dir
To create a file inside a dir use a 4 spaces (or tab)
/dir
file
putting it all together…
/dir
file
/plugins
/mail
/vendor
index.html
/something # this one will fail
file.py
file.py
/ (slash) Creating a tree
from sharpshooter import tree
tree('''
/dir
file
/plugins
/mail
/vendor
index.html
file.py
file2.py
''')
tree doesn't wait to be told. Your files are now there.
- (minus) deleting a tree
tree can also remove dirs and files. You guessed it. With the the - minus symbol
tree = '''
/dir
/plugins
-mail
'''
tree will not ask twice. Your files are gone.
But be mindful this example would also 'create' the dir and plugins folders if they didn't exist. Because tree by nature creates by default.
To read info about a file or folder without creation use colon ':' to indicate read-only.
tree = '''
:/dir
:/plugins
-mail
'''
More on colons : later.
WARNING - be careful using minus. tree could destroy your entire filesytem if used incorrectly
Use # to comment out a line or instruction.
s = '''
/:dir
file# some ignored text here
/plugins
/mail
'''
WARNING - the # symbol is ignored if it comes after the <, $ or > symbols. (see why further down)
: (colon) read only
To read info about a file or folder, without creating any, use a colon ':'
You can then format the tree with an f-string to get the result which produces similir output as 'ls -al' on nix systems i.e.
test = tree('''
:README.md
''')
print(f"{test}")
or for a directory...
test = tree('''
:venv
''')
print(f"{test}")
Notice the little 'd' at the front lets you know it's a directory. Just like in a terminal.
you can safely change change order of colon and plus i.e. will still work.
tree('''
:/dont
:/make
:this
''')
but i prefer to use the colon right before the file or folder name .i.e.
tree('''
/:dont
/:make
:this
''')
up to you.
test mode
If you are feeling unsure. Try tree in test mode.
It will log what it would do to the console but won't actually create any files or folders.
You just have to past test=True to the tree function. i.e
mytree = '''
/somedir
/anotherdir
someotherfile.png
file.txt
file2.gif
'''
tree(mytree, test=True)
Now check the console and if you feel confident set test=False and run the code again.
~ (tilde) users home direcory
users home path is supported.
s1 = """
:/~
test.png
/somedir
somescript.py
"""
tree(s1, test=True)
tree(s1, test=False)
< (lt) write to a file
< This symbol can be used to write a string to a file.
mystring = """
/somedir
somescript.py < print('hello world!')
some.txt < hello world!
script.sh < echo 'hello world'
"""
tree(mystring)
you can use \n to add more than one line to a file.
mystring = """
/somedir
somepage.md < # heading \n## another heading \n### and another heading
"""
tree(mystring)
$ (dollar) pass to the shell
Anything after the $ symbol is passed to the shell and the result is written to the file.
mystring = """
/somedir
test.txt $ cowsay moo
"""
tree(mystring)
> (gt) pass to windows cmd
bash commands won't work on windows. Instead use the > symbol for windows commands
Anything after the > symbol is passed to cmd with the result written to the file.
mystring = """
/somedir
test.txt $ ls -al
test.txt > dir
"""
tree(mystring)
? (question)
A question will take user input. It can be used in place of a filename.
mystring = """
/somedir
somefile.txt
?
anotherfile.txt ?
/?
info.txt
"""
tree(mystring)
In this example a prompt would ask for a filename inbetween creating somefile.txt and anotherfile.txt.
Then a multi-line prompt would ask for content to be input for anotherfile.txt.
Lastly a prompt would ask for the folder name to be created before putting info.txt in it.
#[name] labels
A label is a way to store multiple trees in a single file.
By using square brackets after a # symbol you can label a tree. i.e.
#[mylabel]
/dir
file
You can now pass the label to the tree function.
sharpshooter --test myconfig.tree -l mylabel
Anything else?
To see planned features/goals see TODO.md
CLI
There's several commands you can pass to sharpshooter on the command line.
python3 -m sharpshooter --help
sharpshooter --version
sharpshooter --create someconfigname
sharpshooter --file myconfig.tree
sharpshooter --test anotherconfig.tree
sharpshooter --mock
sharpshooter --dir
sharpshooter --pretty 0
There's an optional feature that requires jinja2:
python -m pip install jinja2
sharpshooter --jinja myconfig.tree arg1=test
- (note. jinja2 is not part of sharpshooter so you need to install it yourself. its an optional CLI dependency)
- (note. jinja2 has no test mode yet so be careful)
NOTES
I came up with the idea while mucking around with a lexer.
https://www.dabeaz.com/ply/
https://github.com/dabeaz/ply
remember it executes from where your python thinks is the current dir.
If you're unsure set it first. i.e.
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))
For your information, tree is the language and sharpshooter is an implementation.
pretty is available on the tree class as a static method.
from sharpshooter import tree
tree.pretty(tree_string)
Contributing
If you think you can write a sharpshooter parser in another language then please do and i'll link to your repo.
To dev on this one locally just pull the repo and do...
cd /sharpshooter
python3 -m venv venv
. venv/bin/activate
pip install -r requirements.txt
python -m sharpshooter -d tests -f test.tree
make test
Or run and write some tests, there's a few to get started in the Makefile.
You can install your own version using...
python3 -m pip install -e .
There's several test.tree files in the /tests you can tweak and run through the CLI.
It creates a tmp folder you can delete and rerun to experiment. i.e.
/tmp
/hello
world.txt < y tho!
page.html < <html>y tho!</html>
/this # some comment
/is
cool.txt $ cowsay cool
cool.txt > dir
test.md < # heading \n## another heading \n### and another heading
page.html $ curl -s https://www.google.com
page2.htm $ curl -s https://www.fileformat.info/info/charset/UTF-32/list.htm
/partial
star.html $ curl -s -r 32-35 https://raw.githubusercontent.com/byteface/domonic/master/docs/_templates/sidebarintro.html
files.txt $ find .
DISCLAIMER / known bugs
Use 4 spaces not tabs.
This is a work in progress. It creates and destroys files on your hard drive. So be careful.
DON'T leave trailing negative space on lines. I use space to change dirs.
comments won't work on lines with bash/windows commands or when writing to file. this is so you can write # symbols to the file.
filenames with special chars #?><$ at start or end may cause issues until escaping them is sorted.