Merge pull request carpentries/styles#446
authorMaxim Belkin <maxim.belkin@gmail.com>
Thu, 12 Dec 2019 15:58:29 +0000 (09:58 -0600)
committerGitHub <noreply@github.com>
Thu, 12 Dec 2019 15:58:29 +0000 (09:58 -0600)
Makefile
bin/lesson_check.py [changed mode: 0755->0644]
bin/lesson_initialize.py [changed mode: 0755->0644]
bin/repo_check.py [changed mode: 0755->0644]
bin/test_lesson_check.py [changed mode: 0755->0644]
bin/util.py
bin/workshop_check.py [changed mode: 0755->0644]

index d291abe66d616bd33e28aec4551ab9e8f36b0cad..5ae969f6ddb2ae93bc9415aceebbd94cb065fbd3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,30 @@ JEKYLL_VERSION=3.8.5
 PARSER=bin/markdown_ast.rb
 DST=_site
 
+# Check Python 3 is installed and determine if it's called via python3 or python
+# (https://stackoverflow.com/a/4933395)
+PYTHON3_EXE := $(shell which python3 2>/dev/null)
+ifneq (, $(PYTHON3_EXE))
+  ifeq (,$(findstring Microsoft/WindowsApps/python3,$(subst \,/,$(PYTHON3_EXE))))
+    PYTHON := python3
+  endif
+endif
+
+ifeq (,$(PYTHON))
+  PYTHON_EXE := $(shell which python 2>/dev/null)
+  ifneq (, $(PYTHON_EXE))
+    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
+endif
+
+
 # Controls
 .PHONY : commands clean files
 .NOTPARALLEL:
@@ -15,7 +39,7 @@ all : commands
 
 ## commands         : show all commands.
 commands :
-       @grep -h -E '^##' ${MAKEFILES} | sed -e 's/## //g'
+       @grep -h -E '^##' ${MAKEFILES} | sed -e "s/## //g"
 
 ## docker-serve     : use docker to build the site
 docker-serve :
@@ -54,7 +78,7 @@ clean-rmd :
 
 ## workshop-check   : check workshop homepage.
 workshop-check :
-       @bin/workshop_check.py .
+       @${PYTHON} bin/workshop_check.py .
 
 ## ----------------------------------------
 ## Commands specific to lesson websites.
@@ -93,15 +117,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 :
old mode 100755 (executable)
new mode 100644 (file)
index 2597da5..ee84d84
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-
 """
 Check lesson files and their contents.
 """
@@ -29,19 +27,19 @@ SOURCE_RMD_DIRS = ['_episodes_rmd']
 # 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$')
+P_EPISODE_FILENAME = re.compile(r'(\d\d)-[-\w]+.md$')
 
 # Pattern to match lines ending with whitespace.
 P_TRAILING_WHITESPACE = re.compile(r'\s+$')
@@ -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)
@@ -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:
@@ -556,7 +557,7 @@ CHECKERS = [
     (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)
 ]
 
old mode 100755 (executable)
new mode 100644 (file)
index 9ba8116..2f7b8e6
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-
 """Initialize a newly-created repository."""
 
 
@@ -14,11 +12,11 @@ BOILERPLATE = (
     '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',
@@ -41,7 +39,7 @@ def main():
     # Create.
     for path in BOILERPLATE:
         shutil.copyfile(
-            "bin/boilerplate/{}".format(path),
+            os.path.join('bin', 'boilerplate', path),
             path
         )
 
old mode 100755 (executable)
new mode 100644 (file)
index af4b782..31651fd
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-
 """
 Check repository settings.
 """
@@ -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]
old mode 100755 (executable)
new mode 100644 (file)
index 960059e..0981720
@@ -1,5 +1,3 @@
-#!/usr/bin/env python3
-
 import unittest
 
 import lesson_check
@@ -12,10 +10,8 @@ class TestFileList(unittest.TestCase):
 
     def test_file_list_has_expected_entries(self):
         # For first pass, simply assume that all required files are present
-        all_filenames = [filename.replace('%', '')
-                         for filename in lesson_check.REQUIRED_FILES]
 
-        lesson_check.check_fileset('', self.reporter, all_filenames)
+        lesson_check.check_fileset('', self.reporter, lesson_check.REQUIRED_FILES)
         self.assertEqual(len(self.reporter.messages), 0)
 
 
index f9dc12f3f612cddc4a2d7eaac727e7940ba329bd..5a46cec03f507649695398994ba4820de1455a1f 100644 (file)
@@ -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)
 
old mode 100755 (executable)
new mode 100644 (file)
index 0523d0c..2caf560
@@ -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.
 '''