Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python scripts: compatibility with Windows #446

Merged
merged 26 commits into from
Dec 12, 2019
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
0cc96db
Forced re-encoding of text to UTF-8, to avoid issues on Windows
JoaoRodrigues Dec 3, 2019
8566047
Refactored paths to make use of OS agnostic methods
JoaoRodrigues Dec 3, 2019
d88b22a
Modified shebang to use python, not python3.
JoaoRodrigues Dec 3, 2019
21a979b
Reverted change of permissiveness on lesson_check
JoaoRodrigues Dec 3, 2019
901c574
Cleaned leftover debug code and old implementations.
JoaoRodrigues Dec 4, 2019
82dd7fb
Added PYTHON variable to define executable to run python scripts
JoaoRodrigues Dec 4, 2019
c9add9b
Reverted variable names
JoaoRodrigues Dec 4, 2019
a2d1a1f
Removed shebang lines from Python scripts to avoid cross-OS problems
JoaoRodrigues Dec 4, 2019
cd41c7b
Fixes encoding problem on Windows systems, with minimal changes to ex…
JoaoRodrigues Dec 5, 2019
db22e7b
Silenced output of PYTHON calls
JoaoRodrigues Dec 5, 2019
4381bcb
Makefile: detect Python 3
maxim-belkin Dec 5, 2019
ff5f567
util.py: remove empty line
maxim-belkin Dec 5, 2019
a61b7f6
Undo optimizations to read_all_markdown
maxim-belkin Dec 5, 2019
bab0fca
Remove executable bits from Python scripts
maxim-belkin Dec 5, 2019
bce2366
lesson_initialize: windows compatibility
maxim-belkin Dec 5, 2019
1a0adfd
lesson_check.py: Windows-compatible regular expression pattern
maxim-belkin Dec 5, 2019
ec294aa
repo_check.py: enforce utf-8 encoding
maxim-belkin Dec 5, 2019
caf3b88
clarify comment on python check block
brownsarahm Dec 6, 2019
d454d59
Makefile: Windows does not like single quotes
maxim-belkin Dec 6, 2019
41605eb
test_lesson_check.py: skip unnecessary steps
maxim-belkin Dec 6, 2019
651af34
Makefile: suppress error message on Windows
maxim-belkin Dec 6, 2019
8eb0425
fix typo in lesson_initialize.py
maxim-belkin Dec 6, 2019
ecb1611
Makefile: suppress another error message on Windows
maxim-belkin Dec 6, 2019
e6622b8
Makefile: handle MS Store's Python 3
maxim-belkin Dec 9, 2019
a732a2b
Makefile: fix syntax in conditional
maxim-belkin Dec 9, 2019
f1cb887
Makefile: fix two more syntax errors in conditionals
maxim-belkin Dec 9, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,21 @@ JEKYLL_VERSION=3.8.5
PARSER=bin/markdown_ast.rb
DST=_site

# Check Python 3 (https://stackoverflow.com/a/4933395)
ifneq (, $(shell which python3))
PYTHON := python3
else ifneq (, $(shell which python))
PYTHON_VERSION_FULL := $(wordlist 2,4,$(subst ., ,$(shell python --version 2>&1)))
PYTHON_VERSION_MAJOR := $(word 1,${PYTHON_VERSION_FULL})
ifneq (3, ${PYTHON_VERSION_MAJOR})
$(error "Your system does not appear to have Python 3 installed.")
endif
PYTHON := python
else
$(error "Your system does not appear to have any Python installed.")
endif


# Controls
.PHONY : commands clean files
.NOTPARALLEL:
Expand Down Expand Up @@ -54,7 +69,7 @@ clean-rmd :

## workshop-check : check workshop homepage.
workshop-check :
@bin/workshop_check.py .
@${PYTHON} bin/workshop_check.py .

## ----------------------------------------
## Commands specific to lesson websites.
Expand Down Expand Up @@ -93,15 +108,15 @@ _episodes/%.md: _episodes_rmd/%.Rmd

## lesson-check : validate lesson Markdown.
lesson-check : lesson-fixme
@bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md
@${PYTHON} bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md

## lesson-check-all : validate lesson Markdown, checking line lengths and trailing whitespace.
lesson-check-all :
@bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w --permissive
@${PYTHON} bin/lesson_check.py -s . -p ${PARSER} -r _includes/links.md -l -w --permissive

## unittest : run unit tests on checking tools.
unittest :
@bin/test_lesson_check.py
@${PYTHON} bin/test_lesson_check.py

## lesson-files : show expected names of generated files for debugging.
lesson-files :
Expand Down
31 changes: 16 additions & 15 deletions bin/lesson_check.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3

"""
Check lesson files and their contents.
"""
Expand Down Expand Up @@ -29,19 +27,19 @@
# specially. This list must include all the Markdown files listed in the
# 'bin/initialize' script.
REQUIRED_FILES = {
'%/CODE_OF_CONDUCT.md': True,
'%/CONTRIBUTING.md': False,
'%/LICENSE.md': True,
'%/README.md': False,
'%/_extras/discuss.md': True,
'%/_extras/guide.md': True,
'%/index.md': True,
'%/reference.md': True,
'%/setup.md': True,
'CODE_OF_CONDUCT.md': True,
'CONTRIBUTING.md': False,
'LICENSE.md': True,
'README.md': False,
os.path.join('_extras', 'discuss.md'): True,
os.path.join('_extras', 'guide.md'): True,
'index.md': True,
'reference.md': True,
'setup.md': True,
}

# Episode filename pattern.
P_EPISODE_FILENAME = re.compile(r'/_episodes/(\d\d)-[-\w]+.md$')
maxim-belkin marked this conversation as resolved.
Show resolved Hide resolved
P_EPISODE_FILENAME = re.compile(r'(\d\d)-[-\w]+.md$')

# Pattern to match lines ending with whitespace.
P_TRAILING_WHITESPACE = re.compile(r'\s+$')
Expand Down Expand Up @@ -272,7 +270,7 @@ def check_fileset(source_dir, reporter, filenames_present):
"""Are all required files present? Are extraneous files present?"""

# Check files with predictable names.
required = [p.replace('%', source_dir) for p in REQUIRED_FILES]
required = [os.path.join(source_dir, p) for p in REQUIRED_FILES]
missing = set(required) - set(filenames_present)
for m in missing:
reporter.add(None, 'Missing required file {0}', m)
Expand All @@ -282,7 +280,10 @@ def check_fileset(source_dir, reporter, filenames_present):
for filename in filenames_present:
if '_episodes' not in filename:
continue
m = P_EPISODE_FILENAME.search(filename)

# split path to check episode name
base_name = os.path.basename(filename)
m = P_EPISODE_FILENAME.search(base_name)
if m and m.group(1):
seen.append(m.group(1))
else:
Expand Down Expand Up @@ -556,7 +557,7 @@ def __init__(self, args, filename, metadata, metadata_len, text, lines, doc):
(re.compile(r'README\.md'), CheckNonJekyll),
(re.compile(r'index\.md'), CheckIndex),
(re.compile(r'reference\.md'), CheckReference),
(re.compile(r'_episodes/.*\.md'), CheckEpisode),
(re.compile(os.path.join('_episodes', '*\.md')), CheckEpisode),
(re.compile(r'.*\.md'), CheckGeneric)
]

Expand Down
14 changes: 6 additions & 8 deletions bin/lesson_initialize.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3

"""Initialize a newly-created repository."""


Expand All @@ -14,11 +12,11 @@
'CONTRIBUTING.md',
'README.md',
'_config.yml',
'_episodes/01-introduction.md',
'_extras/about.md',
'_extras/discuss.md',
'_extras/figures.md',
'_extras/guide.md',
os.path.join('_episodes', '01-introduction.md'),
os.path.join('_extras', 'about.md'),
os.path.join('_extras', 'discuss.md'),
os.path.join('_extras', 'figures.md'),
os.path.join('_extras', 'guide.md'),
'index.md',
'reference.md',
'setup.md',
Expand All @@ -41,7 +39,7 @@ def main():
# Create.
for path in BOILERPLATE:
shutil.copyfile(
"bin/boilerplate/{}".format(path),
os.path.join('bin', 'boilerplate', path)
path
)

Expand Down
4 changes: 1 addition & 3 deletions bin/repo_check.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3

"""
Check repository settings.
"""
Expand Down Expand Up @@ -104,7 +102,7 @@ def get_repo_url(repo_url):
# Guess.
cmd = 'git remote -v'
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE,
close_fds=True, universal_newlines=True)
close_fds=True, universal_newlines=True, encoding='utf-8')
stdout_data, stderr_data = p.communicate()
stdout_data = stdout_data.split('\n')
matches = [P_GIT_REMOTE.match(line) for line in stdout_data]
Expand Down
2 changes: 0 additions & 2 deletions bin/test_lesson_check.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3

import unittest

import lesson_check
Expand Down
2 changes: 1 addition & 1 deletion bin/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def read_markdown(parser, path):
# Parse Markdown.
cmd = 'ruby {0}'.format(parser)
p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE,
close_fds=True, universal_newlines=True)
close_fds=True, universal_newlines=True, encoding='utf-8')
stdout_data, stderr_data = p.communicate(body)
doc = json.loads(stdout_data)

Expand Down
2 changes: 0 additions & 2 deletions bin/workshop_check.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python3

'''Check that a workshop's index.html metadata is valid. See the
docstrings on the checking functions for a summary of the checks.
'''
Expand Down