Skip to content

Commit

Permalink
fixes #860
Browse files Browse the repository at this point in the history
  • Loading branch information
jph00 committed Aug 14, 2022
1 parent 6d27bc7 commit f943b66
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 45 deletions.
32 changes: 16 additions & 16 deletions nbdev/clean.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/11_clean.ipynb.
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/10_clean.ipynb.

# %% auto 0
__all__ = ['nbdev_trust', 'clean_nb', 'process_write', 'nbdev_clean', 'clean_jupyter', 'nbdev_install_hooks']

# %% ../nbs/11_clean.ipynb 2
# %% ../nbs/10_clean.ipynb 2
import ast,warnings,stat
from astunparse import unparse
from textwrap import indent
Expand All @@ -18,7 +18,7 @@
from .sync import *
from .process import first_code_ln

# %% ../nbs/11_clean.ipynb 6
# %% ../nbs/10_clean.ipynb 6
@call_parse
def nbdev_trust(
fname:str=None, # A notebook name or glob to trust
Expand All @@ -44,14 +44,14 @@ def nbdev_trust(
if not NotebookNotary().check_signature(nb): NotebookNotary().sign(nb)
check_fname.touch(exist_ok=True)

# %% ../nbs/11_clean.ipynb 9
# %% ../nbs/10_clean.ipynb 9
_repr_id_re = re.compile('(<.*?)( at 0x[0-9a-fA-F]+)(>)')

def _clean_cell_output_id(lines):
sub = partial(_repr_id_re.sub, r'\1\3')
return sub(lines) if isinstance(lines,str) else [sub(o) for o in lines]

# %% ../nbs/11_clean.ipynb 11
# %% ../nbs/10_clean.ipynb 11
def _clean_cell_output(cell, clean_ids):
"Remove `cell` output execution count and optionally ids from text reprs"
outputs = cell.get('outputs', [])
Expand All @@ -65,7 +65,7 @@ def _clean_cell_output(cell, clean_ids):
if 'text' in o: o['text'] = _clean_cell_output_id(o['text'])
o.get('metadata', {}).pop('tags', None)

# %% ../nbs/11_clean.ipynb 12
# %% ../nbs/10_clean.ipynb 12
def _clean_cell(cell, clear_all, allowed_metadata_keys, clean_ids):
"Clean `cell` by removing superfluous metadata or everything except the input if `clear_all`"
if 'execution_count' in cell: cell['execution_count'] = None
Expand All @@ -76,7 +76,7 @@ def _clean_cell(cell, clear_all, allowed_metadata_keys, clean_ids):
cell['metadata'] = {} if clear_all else {
k:v for k,v in cell['metadata'].items() if k in allowed_metadata_keys}

# %% ../nbs/11_clean.ipynb 13
# %% ../nbs/10_clean.ipynb 13
def clean_nb(
nb, # The notebook to clean
clear_all=False, # Remove all cell metadata and cell outputs
Expand All @@ -92,12 +92,12 @@ def clean_nb(
for c in nb['cells']: _clean_cell(c, clear_all, cell_metadata_keys, clean_ids)
nb['metadata'] = {k:v for k,v in nb['metadata'].items() if k in metadata_keys}

# %% ../nbs/11_clean.ipynb 24
# %% ../nbs/10_clean.ipynb 24
def _reconfigure(*strms):
for s in strms:
if hasattr(s,'reconfigure'): s.reconfigure(encoding='utf-8')

# %% ../nbs/11_clean.ipynb 25
# %% ../nbs/10_clean.ipynb 25
def process_write(warn_msg, proc_nb, f_in, f_out=None, disp=False):
if not f_out: f_out = sys.stdout if disp else f_in
if isinstance(f_in, (str,Path)): f_in = Path(f_in).open()
Expand All @@ -110,7 +110,7 @@ def process_write(warn_msg, proc_nb, f_in, f_out=None, disp=False):
warn(f'{warn_msg}')
warn(e)

# %% ../nbs/11_clean.ipynb 26
# %% ../nbs/10_clean.ipynb 26
def _nbdev_clean(nb, path=None, **kwargs):
cfg = get_config(path=path)
allowed_metadata_keys = cfg.get("allowed_metadata_keys").split()
Expand All @@ -119,7 +119,7 @@ def _nbdev_clean(nb, path=None, **kwargs):
return clean_nb(nb, clean_ids=clean_ids, allowed_metadata_keys=allowed_metadata_keys,
allowed_cell_metadata_keys=allowed_cell_metadata_keys, **kwargs)

# %% ../nbs/11_clean.ipynb 27
# %% ../nbs/10_clean.ipynb 27
@call_parse
def nbdev_clean(
fname:str=None, # A notebook name or glob to clean
Expand All @@ -136,7 +136,7 @@ def nbdev_clean(
if fname is None: fname = get_config().path('nbs_path')
for f in globtastic(fname, file_glob='*.ipynb', skip_folder_re='^[_.]'): _write(f_in=f, disp=disp)

# %% ../nbs/11_clean.ipynb 30
# %% ../nbs/10_clean.ipynb 30
def clean_jupyter(path, model, **kwargs):
"Clean Jupyter `model` pre save to `path`"
if not (model['type']=='notebook' and model['content']['nbformat']==4): return
Expand All @@ -149,7 +149,7 @@ def clean_jupyter(path, model, **kwargs):
else: jupyter_hooks = str2bool(jupyter_hooks)
if jupyter_hooks: _nbdev_clean(model['content'], path=path)

# %% ../nbs/11_clean.ipynb 33
# %% ../nbs/10_clean.ipynb 33
_pre_save_hook_src = '''
def nbdev_clean_jupyter(**kwargs):
try: from nbdev.clean import clean_jupyter
Expand All @@ -159,7 +159,7 @@ def nbdev_clean_jupyter(**kwargs):
c.ContentsManager.pre_save_hook = nbdev_clean_jupyter'''.strip()
_pre_save_hook_re = re.compile(r'c\.(File)?ContentsManager\.pre_save_hook')

# %% ../nbs/11_clean.ipynb 34
# %% ../nbs/10_clean.ipynb 34
def _add_jupyter_hooks(src, path):
if _pre_save_hook_src in src: return
mod = ast.parse(src)
Expand All @@ -177,12 +177,12 @@ def _add_jupyter_hooks(src, path):
if src: src+='\n\n'
return src+_pre_save_hook_src

# %% ../nbs/11_clean.ipynb 38
# %% ../nbs/10_clean.ipynb 38
def _git_root():
try: return Path(run('git rev-parse --show-toplevel'))
except OSError: return None

# %% ../nbs/11_clean.ipynb 41
# %% ../nbs/10_clean.ipynb 41
@call_parse
def nbdev_install_hooks():
"Install Jupyter and git hooks to automatically clean, trust, and fix merge conflicts in notebooks"
Expand Down
48 changes: 24 additions & 24 deletions nbdev/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/10_cli.ipynb.
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/12_cli.ipynb.

# %% ../nbs/10_cli.ipynb 1
# %% ../nbs/12_cli.ipynb 1
from __future__ import annotations
import warnings

Expand All @@ -27,15 +27,15 @@
'extract_tgz', 'prompt_user', 'refresh_quarto_yml', 'nbdev_new', 'install_quarto', 'install', 'nbdev_readme',
'nbdev_quarto', 'preview', 'deploy', 'chelp']

# %% ../nbs/10_cli.ipynb 5
# %% ../nbs/12_cli.ipynb 5
@call_parse
def prepare():
"Export, test, and clean notebooks"
nbdev_export.__wrapped__()
nbdev_test.__wrapped__()
nbdev_clean.__wrapped__()

# %% ../nbs/10_cli.ipynb 7
# %% ../nbs/12_cli.ipynb 7
_def_file_re = '\.(?:ipynb|qmd|html)$'

def _f(a,b): return Path(a),b
Expand Down Expand Up @@ -80,7 +80,7 @@ def nbdev_sidebar(
yml_path.write_text(yml)
if returnit: return files

# %% ../nbs/10_cli.ipynb 10
# %% ../nbs/12_cli.ipynb 10
class FilterDefaults:
"Override `FilterDefaults` to change which notebook processors are used"
def _nothing(self): return []
Expand Down Expand Up @@ -109,7 +109,7 @@ def nb_proc(self, nb):
"Get an `NBProcessor` with these processors"
return NBProcessor(nb=nb, procs=self.procs(), preprocs=self.preprocs(), postprocs=self.postprocs())

# %% ../nbs/10_cli.ipynb 11
# %% ../nbs/12_cli.ipynb 11
@call_parse
def nbdev_filter(
nb_txt:str=None, # Notebook text (uses stdin if not provided)
Expand All @@ -132,7 +132,7 @@ def nbdev_filter(
if printit: print(res, flush=True)
else: return res

# %% ../nbs/10_cli.ipynb 14
# %% ../nbs/12_cli.ipynb 14
def bump_version(version, part=2, unbump=False):
version = version.split('.')
incr = -1 if unbump else 1
Expand All @@ -153,15 +153,15 @@ def nbdev_bump_version(
nbdev_export()
print(f'New version: {cfg.version}')

# %% ../nbs/10_cli.ipynb 16
# %% ../nbs/12_cli.ipynb 16
def extract_tgz(url, dest='.'):
from fastcore.net import urlopen
with urlopen(url) as u: tarfile.open(mode='r:gz', fileobj=u).extractall(dest)

# %% ../nbs/10_cli.ipynb 17
# %% ../nbs/12_cli.ipynb 17
def _mk_cfg(**kwargs): return {k: kwargs.get(k,None) for k in 'lib_name user branch author author_email keywords description repo'.split()}

# %% ../nbs/10_cli.ipynb 18
# %% ../nbs/12_cli.ipynb 18
def _get_info(owner, repo, default_branch='main', default_kw='nbdev'):
from ghapi.all import GhApi
api = GhApi(owner=owner, repo=repo, token=os.getenv('GITHUB_TOKEN'))
Expand All @@ -178,7 +178,7 @@ def _get_info(owner, repo, default_branch='main', default_kw='nbdev'):

return r.default_branch, default_kw if not r.topics else ' '.join(r.topics), r.description

# %% ../nbs/10_cli.ipynb 20
# %% ../nbs/12_cli.ipynb 20
def _fetch_from_git(raise_err=False):
"Get information for settings.ini from the user."
res={}
Expand All @@ -194,7 +194,7 @@ def _fetch_from_git(raise_err=False):
else: res['lib_name'] = res['repo'].replace('-','_')
return res

# %% ../nbs/10_cli.ipynb 22
# %% ../nbs/12_cli.ipynb 22
def prompt_user(cfg, inferred):
"Let user input values not in `cfg` or `inferred`."
print(S.dark_gray('# settings.ini'))
Expand All @@ -210,7 +210,7 @@ def prompt_user(cfg, inferred):
else: print(msg+str(v))
return res

# %% ../nbs/10_cli.ipynb 23
# %% ../nbs/12_cli.ipynb 23
_quarto_yml="""ipynb-filters: [nbdev_filter]
project:
Expand Down Expand Up @@ -264,7 +264,7 @@ def refresh_quarto_yml():
yml=_quarto_yml.format(**vals)
p.write_text(yml)

# %% ../nbs/10_cli.ipynb 24
# %% ../nbs/12_cli.ipynb 24
@call_parse
def nbdev_new(lib_name: str=None): # Package name (default: inferred from repo name)
"Create a new project from the current git repo"
Expand Down Expand Up @@ -297,12 +297,12 @@ def nbdev_new(lib_name: str=None): # Package name (default: inferred from repo n

nbdev_export.__wrapped__()

# %% ../nbs/10_cli.ipynb 26
# %% ../nbs/12_cli.ipynb 26
def _sprun(cmd):
try: subprocess.check_output(cmd, shell=True)
except subprocess.CalledProcessError as cpe: sys.exit(cpe.returncode)

# %% ../nbs/10_cli.ipynb 27
# %% ../nbs/12_cli.ipynb 27
BASE_QUARTO_URL='https://www.quarto.org/download/latest/'

def _install_linux():
Expand Down Expand Up @@ -332,7 +332,7 @@ def install():
if (get_config().path('lib_path')/'__init__.py').exists():
system(f'pip install -e "{_dir()}[dev]"')

# %% ../nbs/10_cli.ipynb 28
# %% ../nbs/12_cli.ipynb 28
def _doc_paths(path:str=None, doc_path:str=None):
cfg = get_config()
cfg_path = cfg.config_path
Expand All @@ -341,7 +341,7 @@ def _doc_paths(path:str=None, doc_path:str=None):
tmp_doc_path = path/f"{cfg['doc_path']}"
return cfg,cfg_path,path,doc_path,tmp_doc_path

# %% ../nbs/10_cli.ipynb 29
# %% ../nbs/12_cli.ipynb 29
def _render_readme(path):
idx_path = path/get_config().readme_nb
if not idx_path.exists(): return
Expand All @@ -357,7 +357,7 @@ def _render_readme(path):
finally:
if moved: (path/'sidebar.yml.bak').rename(yml_path)

# %% ../nbs/10_cli.ipynb 30
# %% ../nbs/12_cli.ipynb 30
@call_parse
def nbdev_readme(
path:str=None, # Path to notebooks
Expand All @@ -370,13 +370,13 @@ def nbdev_readme(
if _rdm.exists(): _rdm.unlink() # py37 doesn't have arg missing_ok so have to check first
shutil.move(str(tmp_doc_path/'README.md'), cfg_path) # README.md is temporarily in nbs/_docs

# %% ../nbs/10_cli.ipynb 31
# %% ../nbs/12_cli.ipynb 31
def _ensure_quarto():
if shutil.which('quarto'): return
print("Quarto is not installed. We will download and install it for you.")
install()

# %% ../nbs/10_cli.ipynb 32
# %% ../nbs/12_cli.ipynb 32
@call_parse
def nbdev_quarto(
path:str=None, # Path to notebooks
Expand All @@ -402,7 +402,7 @@ def nbdev_quarto(
shutil.rmtree(doc_path, ignore_errors=True)
shutil.move(tmp_doc_path, cfg_path)

# %% ../nbs/10_cli.ipynb 33
# %% ../nbs/12_cli.ipynb 33
@call_parse
def preview(
path:str=None, # Path to notebooks
Expand All @@ -417,7 +417,7 @@ def preview(
nbdev_quarto(path, doc_path=doc_path, symlinks=symlinks, file_re=file_re, folder_re=folder_re,
skip_file_glob=skip_file_glob, skip_file_re=skip_file_re, preview=True)

# %% ../nbs/10_cli.ipynb 34
# %% ../nbs/12_cli.ipynb 34
@call_parse
def deploy(
path:str=None, # Path to notebooks
Expand All @@ -437,7 +437,7 @@ def deploy(
except: return warnings.warn('Please install ghp-import with `pip install ghp-import`')
ghp_import(get_config().path('doc_path'), push=True, stderr=True, no_history=True)

# %% ../nbs/10_cli.ipynb 36
# %% ../nbs/12_cli.ipynb 36
@call_parse
def chelp():
"Show help for all console scripts"
Expand Down
10 changes: 5 additions & 5 deletions nbdev/test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/14_test.ipynb.
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/11_test.ipynb.

# %% auto 0
__all__ = ['test_nb', 'nbdev_test']

# %% ../nbs/14_test.ipynb 1
# %% ../nbs/11_test.ipynb 1
import time,os,sys,traceback,contextlib, inspect
from fastcore.basics import *
from fastcore.imports import *
Expand All @@ -20,7 +20,7 @@
from execnb.nbio import *
from execnb.shell import *

# %% ../nbs/14_test.ipynb 3
# %% ../nbs/11_test.ipynb 3
def test_nb(fn, # file name of notebook to test
skip_flags=None, # list of flags marking cells to skip
force_flags=None, # list of flags marking cells to always run
Expand Down Expand Up @@ -55,15 +55,15 @@ def _no_eval(cell):
if do_print: print(f'- Completed {fn}')
return res,time.time()-start

# %% ../nbs/14_test.ipynb 8
# %% ../nbs/11_test.ipynb 8
def _keep_file(p:Path, # filename for which to check for `indicator_fname`
ignore_fname:str # filename that will result in siblings being ignored
) -> bool:
"Returns False if `indicator_fname` is a sibling to `fname` else True"
if p.exists(): return not bool(p.parent.ls().attrgot('name').filter(lambda x: x == ignore_fname))
else: True

# %% ../nbs/14_test.ipynb 10
# %% ../nbs/11_test.ipynb 10
@call_parse
def nbdev_test(
fname:str=None, # A notebook name or glob to test
Expand Down
28 changes: 28 additions & 0 deletions nbs/getting_started.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,34 @@
"!nbdev_help"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Installing Quarto"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that when you setup your first project, nbdev will attempt to automatically download and install [quarto](https://quarto.org/) for you. This is the program that we use to create your documentation website.\n",
"\n",
"Quarto's standard installation process requires root access, and nbdev will therefore ask for your root password during installation. For most people, this will work fine and everything will be handled automatically -- if so, you can skip over the rest of this section, which talks about installing without root access.\n",
"\n",
"If you need to install quarto without root access on Linux, first `cd` to wherever you want to store it, then [download quarto](https://quarto.org/docs/get-started/), and type:\n",
"\n",
"```bash\n",
"dpkg -x quarto*.deb .\n",
"mv opt/quarto ./\n",
"rmdir opt\n",
"mkdir -p ~/.local/bin\n",
"ln -s \"$(pwd)\"/quarto/bin/quarto ~/.local/bin\n",
"```\n",
"\n",
"To use this non-root version of quarto, you'll need `~/.local/bin` in your [`PATH` environment variable](https://linuxize.com/post/how-to-add-directory-to-path-in-linux/). (Alternatively, change the `ln -s` step to place the symlink somewhere else in your path.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down

0 comments on commit f943b66

Please sign in to comment.