Skip to content
This repository has been archived by the owner on May 13, 2019. It is now read-only.

Commit

Permalink
Config development and cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
nickpandolfi committed Dec 30, 2016
1 parent 75d8041 commit 5c07196
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 21 deletions.
1 change: 1 addition & 0 deletions TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ FUTURE UPDATES
Get cyther to modify distutils imported at runtime to compile everything instead of distutils
Make 'path(root='.')' work

Q) Can I use the Python source code from PSF to literally figure out where the include/runtime dirs were installed?
Q) Even bother getting Cyther to work with python 2 or pypy(3)?
Q) Whats up with pypi version badge doing '?.?.?'
Q) Can ar recompile static libraries? (http://www.linux.org/threads/gnu-binutils.6544/)
Expand Down
117 changes: 101 additions & 16 deletions cyther/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,41 @@
import os

from .files import path, USER
from .searcher import find
from .tools import read_dict_from_file, write_dict_to_file, get_input
from .definitions import CONFIG_FILE_NAME, VER, DOT_VER


class IncludeDirectoryError(Exception):
"""A custom error used to denote an error with your include directories"""
none = "No include directory found for this version of python"
no_default = "There appears to be no default include directory; Cyther " \
"was not able to find a suitable directory to default to"

def __init__(self, *args, **kwargs):
super(IncludeDirectoryError, self).__init__(*args, **kwargs)

CONFIG_FILE_NAME = '.cyther'

INCLUDE_DIRS_KEY = 'include_search_directory'
RUNTIME_DIRS_KEY = 'runtime_search_directory'
RUNTIME_KEY = 'runtime_libraries'


def purge_configs():
"""
These will delete any configs found in either the current directory or the
user's home directory
"""
user_config = path(CONFIG_FILE_NAME, root=USER)
inplace_config = path(CONFIG_FILE_NAME)

if os.path.isfile(user_config):
os.remove(user_config)

if os.path.isfile(inplace_config):
os.remove(inplace_config)


def write_config_file(file_path, data):
"""
Writes a config data structure (dict for now) to the file path specified
Expand Down Expand Up @@ -84,11 +110,7 @@ def get_config():
NO_CONFIGS_EXIST = "No configs were found, it's safe " \
"to make the config file anywhere\n"

COMPLEX_PROMPT = "Where do you want to make the config file? " \
"[user/inplace/default/''=exit]: "

COMPLEX_REDO_PROMPT = "Incorrect response, must be 'user', 'inplace', " \
"'default', or '' (empty) to exit: "
COMPLEX_PROMPT = "Where do you want to make the config file?"


def _complex_decision(*, guided):
Expand Down Expand Up @@ -122,9 +144,7 @@ def _complex_decision(*, guided):
print(NO_CONFIGS_EXIST)

# Get the user's response to said situation ^
response = get_input(COMPLEX_PROMPT,
('user', 'inplace', 'default', ''),
redo_prompt=COMPLEX_REDO_PROMPT)
response = get_input(COMPLEX_PROMPT,('user', 'inplace', 'default', ''))

# Decide what to do based on the user's error checked response
if response == 'user':
Expand All @@ -139,19 +159,17 @@ def _complex_decision(*, guided):
else:
result = default

return result
return result, code

SIMPLE_PROMPT = "Do you want to overwrite '{}'? [y/n]: "

SIMPLE_REDO_PROMPT = "Incorrect response, must be 'y' or 'n': "
SIMPLE_PROMPT = "Do you want to overwrite '{}'?"


def _simple_decision(directory, *, guided):
config_name = path(CONFIG_FILE_NAME, root=directory)
if os.path.isfile(config_name):
if guided:
response = get_input(SIMPLE_PROMPT.format(config_name), ('y', 'n'),
redo_prompt=SIMPLE_REDO_PROMPT)
response = get_input(SIMPLE_PROMPT.format(config_name), ('y', 'n'))
if response == 'n':
exit()
return config_name
Expand All @@ -164,19 +182,86 @@ def _make_config_location(*, guided):
if path() == path(USER):
result = _simple_decision(current, guided=guided)
else:
result = _complex_decision(guided=guided)
result, code = _complex_decision(guided=guided)
else:
result = _simple_decision(current, guided=guided)

return result


INCLUDE_PROMPT = "Choose the number of one of the listed include directories" \
" above, or enter 'default' to do what Cyther thinks is best"


# TODO Implement support if there was only one include dir found by 'find'
def _make_include_dirs(*, guided):
include_dirs = find(['include', 'Python.h'], content="Py_PYTHON_H")

include = None
for include_path in include_dirs:
# TODO This is your current condition... This may not be accurate
if VER in include_path or DOT_VER in include_path:
if not include:
include = os.path.dirname(include_path)
else:
if not guided:
raise Exception()

if guided:
checker = []
for offset, include_path in enumerate(include_dirs):
number = offset + 1
print("{}): '{}'\n".format(number, include_path))
checker.append(number)

response = get_input(INCLUDE_PROMPT, tuple(checker) + ('default', ''))
if not response:
exit()
return
elif response == 'default':
if not include:
raise IncludeDirectoryError(IncludeDirectoryError.no_default)
else:
offset = int(response) - 1
include = include_dirs[offset]
else:
if not include:
raise IncludeDirectoryError(IncludeDirectoryError.none)

return include


def _make_runtime_dirs(*, guided):
return []


def _make_runtime(*, guided):
return ''


def make_config_data(*, guided):
"""
Makes the data necessary to construct a functional config file
"""
config_data = {}
config_data[INCLUDE_DIRS_KEY] = _make_include_dirs(guided=guided)
config_data[RUNTIME_DIRS_KEY] = _make_runtime_dirs(guided=guided)
config_data[RUNTIME_KEY] = _make_runtime(guided=guided)

return config_data


def make_config(guided=False):
"""
Options: --auto, --guided, --manual
Places for the file: --inplace, --user
"""
return _make_config_location(guided=guided)
config_path = _make_config_location(guided=guided)

config_data = make_config_data(guided=guided)

write_config_file(config_path, config_data)
#return config_path


def generate_configurations():
Expand Down
12 changes: 12 additions & 0 deletions cyther/definitions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@

import sys

CACHE_NAME = "__cythercache__"
CONFIG_FILE_NAME = '.cyther'

MAJOR = str(sys.version_info.major)
MINOR = str(sys.version_info.minor)
VER = MAJOR + MINOR
DOT_VER = MAJOR + '.' + MINOR

###############################################################################

FINE = 0
ERROR_PASSOFF = 1
SKIPPED_COMPILATION = 1337
Expand Down
5 changes: 2 additions & 3 deletions cyther/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

from .tools import get_input
from .files import path, ISDIR

CACHE_NAME = "__cythercache__"
from .definitions import CACHE_NAME


def assure_cache(project_path=None):
Expand Down Expand Up @@ -54,7 +53,7 @@ def purge_project():
print("\tNothing was found in the cache")

check_response = get_input("Delete all these files? (^)"
"[y/n]: ", ('y', 'n'))
"[y/n]: ", ('y', 'n'))
if check_response == 'y':
for filepath in to_delete:
os.remove(filepath)
Expand Down
11 changes: 9 additions & 2 deletions cyther/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,22 @@ def read_dict_from_file(file_path):
RESPONSES_ERROR = "Argument 'acceptableResponses' cannot be of type: '{}'"


# TODO Make get_input take the 'check' parameter and inject it into the prompt
def get_input(prompt, check, *, redo_prompt=None):
def get_input(prompt, check, *, redo_prompt=None, repeat_prompt=False):
"""
Ask the user to input something on the terminal level, check their response
and ask again if they didn't answer correctly
"""
if isinstance(check, str):
check = (check,)

prompt += " [{}]: ".format('/'.join(check))

if repeat_prompt:
redo_prompt = prompt
elif not redo_prompt:
redo_prompt = "Incorrect input, please choose from {}: " \
"".format(str(check))

if callable(check):
def checker(r): return check(r)
elif isinstance(check, tuple):
Expand Down

0 comments on commit 5c07196

Please sign in to comment.