Merge pull request #422 from cheat/refactor

Refactor
This commit is contained in:
Chris Allen Lane 2019-02-04 09:58:24 -05:00 committed by GitHub
commit aa33a36491
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 322 additions and 336 deletions

View File

@ -83,13 +83,13 @@ with your [dotfiles][].
Configuring Configuring
----------- -----------
### Setting a CHEAT_DEFAULT_DIR ### ### Setting a CHEAT_USER_DIR ###
Personal cheatsheets are saved in the `~/.cheat` directory by default, but you Personal cheatsheets are saved in the `~/.cheat` directory by default, but you
can specify a different default by exporting a `CHEAT_DEFAULT_DIR` environment can specify a different default by exporting a `CHEAT_USER_DIR` environment
variable: variable:
```sh ```sh
export CHEAT_DEFAULT_DIR='/path/to/my/cheats' export CHEAT_USER_DIR='/path/to/my/cheats'
``` ```
### Setting a CHEAT_PATH ### ### Setting a CHEAT_PATH ###

View File

@ -13,7 +13,7 @@ Usage:
cheat -v cheat -v
Options: Options:
-d --directories List directories on CHEATPATH -d --directories List directories on $CHEAT_PATH
-e --edit Edit cheatsheet -e --edit Edit cheatsheet
-l --list List cheatsheets -l --list List cheatsheets
-s --search Search cheatsheets for <keyword> -s --search Search cheatsheets for <keyword>
@ -36,27 +36,57 @@ Examples:
# require the dependencies # require the dependencies
from __future__ import print_function from __future__ import print_function
from cheat.sheets import Sheets from cheat.colorize import Colorize
from cheat.sheet import Sheet
from cheat.utils import Utils
from cheat.configuration import Configuration from cheat.configuration import Configuration
from cheat.sheet import Sheet
from cheat.sheets import Sheets
from cheat.utils import Utils
from docopt import docopt from docopt import docopt
import os import os
if __name__ == '__main__': if __name__ == '__main__':
# parse the command-line options # parse the command-line options
options = docopt(__doc__, version='cheat 2.4.2') options = docopt(__doc__, version='cheat 2.4.2')
# initialize and validate configs
config = Configuration() config = Configuration()
config.validate()
# create the CHEAT_USER_DIR if it does not exist
if not os.path.isdir(config.cheat_user_dir):
try:
os.mkdir(config.cheat_user_dir)
except OSError:
Utils.die("%s %s %s" % (
'Could not create CHEAT_USER_DIR (',
config.cheat_user_dir,
')')
)
# assert that the CHEAT_USER_DIR is readable and writable
if not os.access(config.cheat_user_dir, os.R_OK):
Utils.die("%s %s %s" % (
'The CHEAT_USER_DIR (',
config.cheat_user_dir,
') is not readable')
)
if not os.access(config.cheat_user_dir, os.W_OK):
Utils.die("%s %s %s" % (
'The CHEAT_USER_DIR (',
config.cheat_user_dir,
') is not writeable')
)
# bootsrap
sheets = Sheets(config) sheets = Sheets(config)
utils = Utils(config) sheet = Sheet(config, sheets)
sheet = Sheet(sheets, utils) colorize = Colorize(config)
# list directories # list directories
if options['--directories']: if options['--directories']:
print("\n".join(sheets.paths())) print("\n".join(sheets.directories()))
# list cheatsheets # list cheatsheets
elif options['--list']: elif options['--list']:
@ -64,12 +94,12 @@ if __name__ == '__main__':
# create/edit cheatsheet # create/edit cheatsheet
elif options['--edit']: elif options['--edit']:
sheet.create_or_edit(options['<cheatsheet>']) sheet.edit(options['<cheatsheet>'])
# search among the cheatsheets # search among the cheatsheets
elif options['--search']: elif options['--search']:
print(utils.colorize(sheets.search(options['<keyword>'])), end="") print(colorize.syntax(sheets.search(options['<keyword>'])), end="")
# print the cheatsheet # print the cheatsheet
else: else:
print(utils.colorize(sheet.read(options['<cheatsheet>'])), end="") print(colorize.syntax(sheet.read(options['<cheatsheet>'])), end="")

View File

@ -1,4 +0,0 @@
from . import sheet
from . import sheets
from . import utils
from . import configuration

62
cheat/colorize.py Normal file
View File

@ -0,0 +1,62 @@
from __future__ import print_function
import sys
class Colorize:
def __init__(self, config):
self._config = config
def search(self, needle, haystack):
""" Colorizes search results matched within a line """
# if a highlight color is not configured, exit early
if not self._config.cheat_highlight:
return haystack
# otherwise, attempt to import the termcolor library
try:
from termcolor import colored
# if the import fails, return uncolored text
except ImportError:
return haystack
# if the import succeeds, colorize the needle in haystack
return haystack.replace(needle,
colored(needle, self._config.cheat_highlight))
def syntax(self, sheet_content):
""" Applies syntax highlighting """
# only colorize if cheat_colors is true, and stdout is a tty
if self._config.cheat_colors is False or not sys.stdout.isatty():
return sheet_content
# don't attempt to colorize an empty cheatsheet
if not sheet_content.strip():
return ""
# otherwise, attempt to import the pygments library
try:
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import TerminalFormatter
# if the import fails, return uncolored text
except ImportError:
return sheet_content
# otherwise, attempt to colorize
first_line = sheet_content.splitlines()[0]
lexer = get_lexer_by_name('bash')
# apply syntax-highlighting if the first line is a code-fence
if first_line.startswith('```'):
sheet_content = '\n'.join(sheet_content.split('\n')[1:-2])
try:
lexer = get_lexer_by_name(first_line[3:])
except Exception:
pass
return highlight(sheet_content, lexer, TerminalFormatter())

View File

@ -1,134 +1,107 @@
import os
from cheat.utils import Utils from cheat.utils import Utils
import json import json
import os
class Configuration: class Configuration:
def __init__(self): def __init__(self):
self._get_global_conf_file_path() # compute the location of the config files
self._get_local_conf_file_path() config_file_path_global = self._select([
self._saved_configuration = self._get_configuration() os.environ.get('CHEAT_GLOBAL_CONF_PATH'),
'/etc/cheat',
def _get_configuration(self): ])
# get options from config files and environment vairables config_file_path_local = self._select([
merged_config = {} os.environ.get('CHEAT_LOCAL_CONF_PATH'),
os.path.expanduser('~/.config/cheat/cheat'),
])
# attempt to read the global config file
config = {}
try: try:
merged_config.update( config.update(self._read_config_file(config_file_path_global))
self._read_configuration_file(self.glob_config_path)
)
except Exception as e: except Exception as e:
Utils.warn('error while parsing global configuration Reason: ' Utils.warn('Error while parsing global configuration: '
+ e.message + e.message)
)
# attempt to read the local config file
try: try:
merged_config.update( config.update(self._read_config_file(config_file_path_local))
self._read_configuration_file(self.local_config_path)
)
except Exception as e: except Exception as e:
Utils.warn('error while parsing user configuration Reason: ' Utils.warn('Error while parsing local configuration: ' + e.message)
+ e.message
)
merged_config.update(self._read_env_vars_config()) # With config files read, now begin to apply envvar overrides and
# default values
self._check_configuration(merged_config) # self.cheat_colors
self.cheat_colors = self._select([
Utils.boolify(os.environ.get('CHEAT_COLORS')),
Utils.boolify(os.environ.get('CHEATCOLORS')),
Utils.boolify(config.get('CHEAT_COLORS')),
True,
])
return merged_config # self.cheat_user_dir
self.cheat_user_dir = self._select([
os.environ.get('CHEAT_USER_DIR'),
os.environ.get('CHEAT_DEFAULT_DIR'),
os.environ.get('DEFAULT_CHEAT_DIR'),
# TODO: XDG home?
os.path.expanduser(
os.path.expandvars(os.path.join('~', '.cheat'))
),
])
def _read_configuration_file(self, path): # self.cheat_editor
# Reads configuration file and returns list of set variables self.cheat_editor = self._select([
read_config = {} os.environ.get('CHEAT_EDITOR'),
if (os.path.isfile(path)): os.environ.get('EDITOR'),
os.environ.get('VISUAL'),
config.get('CHEAT_EDITOR'),
'vi',
])
# self.cheat_highlight
self.cheat_highlight = self._select([
os.environ.get('CHEAT_HIGHLIGHT'),
config.get('CHEAT_HIGHLIGHT'),
False,
])
if isinstance(self.cheat_highlight, str):
Utils.boolify(self.cheat_highlight)
# self.cheat_path
self.cheat_path = self._select([
os.environ.get('CHEAT_PATH'),
os.environ.get('CHEATPATH'),
config.get('CHEAT_PATH'),
'/usr/share/cheat',
])
def _read_config_file(self, path):
""" Reads configuration file and returns list of set variables """
config = {}
if os.path.isfile(path):
with open(path) as config_file: with open(path) as config_file:
read_config.update(json.load(config_file)) config.update(json.load(config_file))
return read_config return config
def _read_env_vars_config(self): def _select(self, values):
read_config = {} for v in values:
if v is not None:
return v
# NOTE: These variables are left here because of backwards def validate(self):
# compatibility and are supported only as env vars but not in """ Validates configuration parameters """
# configuration file
if (os.environ.get('VISUAL')): # assert that cheat_highlight contains a valid value
read_config['EDITOR'] = os.environ.get('VISUAL') highlights = [
# variables supported both in environment and configuration file
# NOTE: Variables without CHEAT_ prefix are legacy
# key is variable name and value is its legacy_alias
# if variable has no legacy alias then set to None
variables = {'CHEAT_DEFAULT_DIR': 'DEFAULT_CHEAT_DIR',
'CHEAT_PATH': 'CHEATPATH',
'CHEAT_COLORS': 'CHEATCOLORS',
'CHEAT_EDITOR': 'EDITOR',
'CHEAT_HIGHLIGHT': None
}
for (k, v) in variables.items():
self._read_env_var(read_config, k, v)
return read_config
def _check_configuration(self, config):
""" Check values in config and warn user or die """
# validate CHEAT_HIGHLIGHT values if set
colors = [
'grey', 'red', 'green', 'yellow', 'grey', 'red', 'green', 'yellow',
'blue', 'magenta', 'cyan', 'white' 'blue', 'magenta', 'cyan', 'white',
False
] ]
if ( if self.cheat_highlight not in highlights:
config.get('CHEAT_HIGHLIGHT') and Utils.die("%s %s" %
config.get('CHEAT_HIGHLIGHT') not in colors ('CHEAT_HIGHLIGHT must be one of:', highlights))
):
Utils.die("%s %s" % ('CHEAT_HIGHLIGHT must be one of:', colors))
def _read_env_var(self, current_config, key, alias=None): return True
if os.environ.get(key) is not None:
current_config[key] = os.environ.get(key)
return
elif alias is not None and os.environ.get(alias) is not None:
current_config[key] = os.environ.get(alias)
return
def _get_global_conf_file_path(self):
self.glob_config_path = (os.environ.get('CHEAT_GLOBAL_CONF_PATH')
or '/etc/cheat')
def _get_local_conf_file_path(self):
path = (os.environ.get('CHEAT_LOCAL_CONF_PATH')
or os.path.expanduser('~/.config/cheat/cheat'))
self.local_config_path = path
def _choose_value(self, primary_value_name, secondary_value_name):
""" Return primary or secondary value in saved_configuration
If primary value is in configuration then return it. If it is not
then return secondary. In the absence of both values return None
"""
primary_value = self._saved_configuration.get(primary_value_name)
secondary_value = self._saved_configuration.get(secondary_value_name)
if primary_value is not None:
return primary_value
else:
return secondary_value
def get_default_cheat_dir(self):
return self._choose_value('CHEAT_DEFAULT_DIR', 'DEFAULT_CHEAT_DIR')
def get_cheatpath(self):
return self._choose_value('CHEAT_PATH', 'CHEATPATH')
def get_cheatcolors(self):
return self._choose_value('CHEAT_COLORS', 'CHEATCOLORS')
def get_editor(self):
return self._choose_value('CHEAT_EDITOR', 'EDITOR')
def get_highlight(self):
return self._saved_configuration.get('CHEAT_HIGHLIGHT')

29
cheat/editor.py Normal file
View File

@ -0,0 +1,29 @@
from __future__ import print_function
from cheat.utils import Utils
import subprocess
class Editor:
def __init__(self, config):
self._config = config
def editor(self):
""" Determines the user's preferred editor """
# assert that the editor is set
if not self._config.cheat_editor:
Utils.die(
'You must set a CHEAT_EDITOR, VISUAL, or EDITOR environment '
'variable or setting in order to create/edit a cheatsheet.'
)
return self._config.cheat_editor
def open(self, filepath):
""" Open `filepath` using the EDITOR specified by the env variables """
editor_cmd = self.editor().split()
try:
subprocess.call(editor_cmd + [filepath])
except OSError:
Utils.die('Could not launch ' + self.editor())

View File

@ -1,79 +1,64 @@
from cheat.editor import Editor
from cheat.utils import Utils
import io import io
import os import os
import shutil import shutil
from cheat.utils import Utils
class Sheet: class Sheet:
def __init__(self, sheets, utils): def __init__(self, config, sheets):
self._config = config
self._editor = Editor(config)
self._sheets = sheets self._sheets = sheets
self._utils = utils
def copy(self, current_sheet_path, new_sheet_path): def _exists(self, sheet):
""" Copies a sheet to a new path """
# attempt to copy the sheet to DEFAULT_CHEAT_DIR
try:
shutil.copy(current_sheet_path, new_sheet_path)
# fail gracefully if the cheatsheet cannot be copied. This can happen
# if DEFAULT_CHEAT_DIR does not exist
except IOError:
Utils.die('Could not copy cheatsheet for editing.')
def create_or_edit(self, sheet):
""" Creates or edits a cheatsheet """
# if the cheatsheet does not exist
if not self.exists(sheet):
self.create(sheet)
# if the cheatsheet exists but not in the default_path, copy it to the
# default path before editing
elif self.exists(sheet) and not self.exists_in_default_path(sheet):
self.copy(self.path(sheet),
os.path.join(self._sheets.default_path(), sheet))
self.edit(sheet)
# if it exists and is in the default path, then just open it
else:
self.edit(sheet)
def create(self, sheet):
""" Creates a cheatsheet """
new_sheet_path = os.path.join(self._sheets.default_path(), sheet)
self._utils.open_with_editor(new_sheet_path)
def edit(self, sheet):
""" Opens a cheatsheet for editing """
self._utils.open_with_editor(self.path(sheet))
def exists(self, sheet):
""" Predicate that returns true if the sheet exists """ """ Predicate that returns true if the sheet exists """
return (sheet in self._sheets.get() and return (sheet in self._sheets.get() and
os.access(self.path(sheet), os.R_OK)) os.access(self._path(sheet), os.R_OK))
def exists_in_default_path(self, sheet): def _exists_in_default_path(self, sheet):
""" Predicate that returns true if the sheet exists in default_path""" """ Predicate that returns true if the sheet exists in default_path"""
default_path_sheet = os.path.join(self._sheets.default_path(), sheet) default_path = os.path.join(self._config.cheat_user_dir, sheet)
return (sheet in self._sheets.get() and return (sheet in self._sheets.get() and
os.access(default_path_sheet, os.R_OK)) os.access(default_path, os.R_OK))
def is_writable(self, sheet): def _path(self, sheet):
""" Predicate that returns true if the sheet is writeable """
return (sheet in self._sheets.get() and
os.access(self.path(sheet), os.W_OK))
def path(self, sheet):
""" Returns a sheet's filesystem path """ """ Returns a sheet's filesystem path """
return self._sheets.get()[sheet] return self._sheets.get()[sheet]
def edit(self, sheet):
""" Creates or edits a cheatsheet """
# if the cheatsheet does not exist
if not self._exists(sheet):
new_path = os.path.join(self._config.cheat_user_dir, sheet)
self._editor.open(new_path)
# if the cheatsheet exists but not in the default_path, copy it to the
# default path before editing
elif self._exists(sheet) and not self._exists_in_default_path(sheet):
try:
shutil.copy(
self._path(sheet),
os.path.join(self._config.cheat_user_dir, sheet)
)
# fail gracefully if the cheatsheet cannot be copied. This can
# happen if CHEAT_USER_DIR does not exist
except IOError:
Utils.die('Could not copy cheatsheet for editing.')
self._editor.open(self._path(sheet))
# if it exists and is in the default path, then just open it
else:
self._editor.open(self._path(sheet))
def read(self, sheet): def read(self, sheet):
""" Returns the contents of the cheatsheet as a String """ """ Returns the contents of the cheatsheet as a String """
if not self.exists(sheet): if not self._exists(sheet):
Utils.die('No cheatsheet found for ' + sheet) Utils.die('No cheatsheet found for ' + sheet)
with io.open(self.path(sheet), encoding='utf-8') as cheatfile: with io.open(self._path(sheet), encoding='utf-8') as cheatfile:
return cheatfile.read() return cheatfile.read()

View File

@ -1,55 +1,34 @@
from cheat.colorize import Colorize
from cheat.utils import Utils
import io import io
import os import os
from cheat.utils import Utils
class Sheets: class Sheets:
def __init__(self, config): def __init__(self, config):
self._default_cheat_dir = config.get_default_cheat_dir() self._config = config
self._cheatpath = config.get_cheatpath() self._colorize = Colorize(config)
self._utils = Utils(config)
def default_path(self): # Assembles a dictionary of cheatsheets as name => file-path
""" Returns the default cheatsheet path """ self._sheets = {}
sheet_paths = [
config.cheat_user_dir
]
# determine the default cheatsheet dir # merge the CHEAT_PATH paths into the sheet_paths
default_sheets_dir = (self._default_cheat_dir or if config.cheat_path:
os.path.join('~', '.cheat')) for path in config.cheat_path.split(os.pathsep):
default_sheets_dir = os.path.expanduser( if os.path.isdir(path):
os.path.expandvars(default_sheets_dir)) sheet_paths.append(path)
# create the DEFAULT_CHEAT_DIR if it does not exist if not sheet_paths:
if not os.path.isdir(default_sheets_dir): Utils.die('The CHEAT_USER_DIR dir does not exist '
try: + 'or the CHEAT_PATH is not set.')
# @kludge: unclear on why this is necessary
os.umask(0000)
os.mkdir(default_sheets_dir)
except OSError:
Utils.die('Could not create DEFAULT_CHEAT_DIR')
# assert that the DEFAULT_CHEAT_DIR is readable and writable
if not os.access(default_sheets_dir, os.R_OK):
Utils.die('The DEFAULT_CHEAT_DIR ('
+ default_sheets_dir
+ ') is not readable.')
if not os.access(default_sheets_dir, os.W_OK):
Utils.die('The DEFAULT_CHEAT_DIR ('
+ default_sheets_dir
+ ') is not writable.')
# return the default dir
return default_sheets_dir
def get(self):
""" Assembles a dictionary of cheatsheets as name => file-path """
cheats = {}
# otherwise, scan the filesystem # otherwise, scan the filesystem
for cheat_dir in reversed(self.paths()): for cheat_dir in reversed(sheet_paths):
cheats.update( self._sheets.update(
dict([ dict([
(cheat, os.path.join(cheat_dir, cheat)) (cheat, os.path.join(cheat_dir, cheat))
for cheat in os.listdir(cheat_dir) for cheat in os.listdir(cheat_dir)
@ -58,26 +37,22 @@ class Sheets:
]) ])
) )
return cheats def directories(self):
def paths(self):
""" Assembles a list of directories containing cheatsheets """ """ Assembles a list of directories containing cheatsheets """
sheet_paths = [ sheet_paths = [
self.default_path(), self._config.cheat_user_dir,
] ]
# merge the CHEATPATH paths into the sheet_paths # merge the CHEATPATH paths into the sheet_paths
if self._cheatpath: for path in self._config.cheat_path.split(os.pathsep):
for path in self._cheatpath.split(os.pathsep):
if os.path.isdir(path):
sheet_paths.append(path) sheet_paths.append(path)
if not sheet_paths:
Utils.die('The DEFAULT_CHEAT_DIR dir does not exist '
+ 'or the CHEATPATH is not set.')
return sheet_paths return sheet_paths
def get(self):
""" Returns a dictionary of cheatsheets as name => file-path """
return self._sheets
def list(self): def list(self):
""" Lists the available cheatsheets """ """ Lists the available cheatsheets """
sheet_list = '' sheet_list = ''
@ -94,7 +69,7 @@ class Sheets:
match = '' match = ''
for line in io.open(cheatsheet[1], encoding='utf-8'): for line in io.open(cheatsheet[1], encoding='utf-8'):
if term in line: if term in line:
match += ' ' + self._utils.highlight(term, line) match += ' ' + self._colorize.search(term, line)
if match != '': if match != '':
result += cheatsheet[0] + ":\n" + match + "\n" result += cheatsheet[0] + ":\n" + match + "\n"

View File

@ -1,100 +1,26 @@
from __future__ import print_function from __future__ import print_function
import os
import subprocess
import sys import sys
class Utils: class Utils:
def __init__(self, config):
self._displaycolors = config.get_cheatcolors()
self._editor_executable = config.get_editor()
self._highlight_color = config.get_highlight()
def highlight(self, needle, haystack):
""" Highlights a search term matched within a line """
# if a highlight color is not configured, exit early
if not self._highlight_color:
return haystack
# otherwise, attempt to import the termcolor library
try:
from termcolor import colored
# if the import fails, return uncolored text
except ImportError:
return haystack
# if the import succeeds, colorize the needle in haystack
return haystack.replace(needle, colored(needle, self._highlight_color))
def colorize(self, sheet_content):
""" Colorizes cheatsheet content if so configured """
# cover all possible positive values to be safe
positive_values = ["True", "true", "1", 1, True]
# only colorize if configured to do so, and if stdout is a tty
if (self._displaycolors not in positive_values or
not sys.stdout.isatty()):
return sheet_content
# don't attempt to colorize an empty cheatsheet
if not sheet_content.strip():
return ""
# otherwise, attempt to import the pygments library
try:
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import TerminalFormatter
# if the import fails, return uncolored text
except ImportError:
return sheet_content
# otherwise, attempt to colorize
first_line = sheet_content.splitlines()[0]
lexer = get_lexer_by_name('bash')
# apply syntax-highlighting if the first line is a code-fence
if first_line.startswith('```'):
sheet_content = '\n'.join(sheet_content.split('\n')[1:-2])
try:
lexer = get_lexer_by_name(first_line[3:])
except Exception:
pass
return highlight(sheet_content, lexer, TerminalFormatter())
@staticmethod @staticmethod
def die(message): def die(message):
""" Prints a message to stderr and then terminates """ """ Prints a message to stderr and then terminates """
Utils.warn(message) Utils.warn(message)
exit(1) exit(1)
def editor(self):
""" Determines the user's preferred editor """
# assert that the editor is set
if (not self._editor_executable):
Utils.die(
'You must set a CHEAT_EDITOR, VISUAL, or EDITOR environment '
'variable or setting in order to create/edit a cheatsheet.'
)
return self._editor_executable
def open_with_editor(self, filepath):
""" Open `filepath` using the EDITOR specified by the env variables """
editor_cmd = self.editor().split()
try:
subprocess.call(editor_cmd + [filepath])
except OSError:
Utils.die('Could not launch ' + self.editor())
@staticmethod @staticmethod
def warn(message): def warn(message):
""" Prints a message to stderr """ """ Prints a message to stderr """
print((message), file=sys.stderr) print((message), file=sys.stderr)
@staticmethod
def boolify(value):
""" Type-converts 'true' and 'false' to Booleans """
# if `value` is not a string, return it as-is
if not isinstance(value, str):
return value
# otherwise, convert "true" and "false" to Boolean counterparts
return value.strip().lower() == "true"

10
ci/lint.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh
# Resolve the app root
SCRIPT=`realpath $0`
SCRIPTPATH=`dirname $SCRIPT`
APPROOT=`realpath "$SCRIPTPATH/.."`
flake8 $APPROOT/setup.py
flake8 $APPROOT/bin/cheat
flake8 $APPROOT/cheat/*.py

View File

@ -1,5 +1,5 @@
{ {
"CHEAT_COLORS": true, "CHEAT_COLORS" : true,
"CHEAT_EDITOR":"vi", "CHEAT_EDITOR" : "vi",
"CHEAT_PATH":"/usr/share/cheat" "CHEAT_PATH" : "/usr/share/cheat"
} }

View File

@ -9,31 +9,31 @@ cheat_path = os.environ.get('CHEAT_PATH') or '/usr/share/cheat'
# aggregate the systme-wide cheatsheets # aggregate the systme-wide cheatsheets
cheat_files = [] cheat_files = []
for f in os.listdir('cheat/cheatsheets/'): for f in os.listdir('cheat/cheatsheets/'):
cheat_files.append(os.path.join('cheat/cheatsheets/',f)) cheat_files.append(os.path.join('cheat/cheatsheets/', f))
# specify build params # specify build params
setup( setup(
name = 'cheat', name='cheat',
version = '2.4.2', version='2.4.2',
author = 'Chris Lane', author='Chris Lane',
author_email = 'chris@chris-allen-lane.com', author_email='chris@chris-allen-lane.com',
license = 'GPL3', license='GPL3',
description = 'cheat allows you to create and view interactive cheatsheets ' description='cheat allows you to create and view interactive cheatsheets '
'on the command-line. It was designed to help remind *nix system ' 'on the command-line. It was designed to help remind *nix system '
'administrators of options for commands that they use frequently, but not ' 'administrators of options for commands that they use frequently, but not '
'frequently enough to remember.', 'frequently enough to remember.',
url = 'https://github.com/chrisallenlane/cheat', url='https://github.com/chrisallenlane/cheat',
packages = [ packages=[
'cheat', 'cheat',
'cheat.test', 'cheat.test',
], ],
scripts = ['bin/cheat'], scripts=['bin/cheat'],
install_requires = [ install_requires=[
'docopt >= 0.6.1', 'docopt >= 0.6.1',
'pygments >= 1.6.0', 'pygments >= 1.6.0',
'termcolor >= 1.1.0', 'termcolor >= 1.1.0',
], ],
data_files = [ data_files=[
(cheat_path, cheat_files), (cheat_path, cheat_files),
('/etc', ['config/cheat']), ('/etc', ['config/cheat']),
], ],