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

Streamline nbdev_new: outputs are now in color, you can pass --lib_name, and it calls nbdev_export #820

Merged
merged 2 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
68 changes: 40 additions & 28 deletions nbdev/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from execnb.nbio import *
from fastcore.utils import *
from fastcore.script import call_parse
from fastcore.style import S
from fastcore import shutil

from urllib.error import HTTPError
Expand Down Expand Up @@ -170,6 +171,9 @@ def extract_tgz(url, dest='.'):
with urlopen(url) as u: tarfile.open(mode='r:gz', fileobj=u).extractall(dest)

# %% ../nbs/10_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
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 @@ -186,35 +190,38 @@ 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 19
def prompt_user(**kwargs):
config_vals = kwargs
print('================ nbdev Configuration ================\n')
for v in config_vals:
if not config_vals[v]:
print('\nPlease enter information for the following field in settings.ini:')
inp = input(f'{v}: ')
config_vals[v] = inp
else: print(f"{v}: '{config_vals[v]}' Automatically inferred from git.")
print(f"\n`settings.ini` updated with configuration values.")
return config_vals

# %% ../nbs/10_cli.ipynb 20
def _fetch_from_git(raise_err=False):
"Get information for settings.ini from the user."
res = {}
try:
url = run('git config --get remote.origin.url')
author = run('git config --get user.name').strip()
email = run('git config --get user.email').strip()
owner,repo = repo_details(url)
branch,keywords,descrip = _get_info(owner=owner, repo=repo)
res['author'] = run('git config --get user.name').strip()
res['author_email'] = run('git config --get user.email').strip()
res['user'],res['repo'] = repo_details(url)
res['branch'],res['keywords'],res['description'] = _get_info(owner=res['user'], repo=res['repo'])
except OSError as e:
if raise_err: raise(e)
return dict(lib_name=None,user=None,branch=None,author=None,author_email=None,keywords=None,description=None,repo=None)
return dict(lib_name=repo.replace('-', '_'), user=owner, branch=branch, author=author,
author_email=email, keywords=keywords, description=descrip, repo=repo)
else: res['lib_name'] = res['repo'].replace('-','_')
return res

# %% ../nbs/10_cli.ipynb 22
def prompt_user(cfg, inferred):
"Let user input values not in `cfg` or `inferred`."
print(S.dark_gray('# settings.ini'))
res = cfg.copy()
for k,v in cfg.items():
inf = inferred.get(k,None)
msg = S.light_blue(k) + ' = '
if v is None:
if inf is None: res[k] = input(S.dark_gray(f'# Please enter a value for {k}\n')+msg)
else:
res[k] = inf
print(msg+res[k]+S.dark_gray(' # Automatically inferred from git'))
else: print(msg+str(v))
return res

# %% ../nbs/10_cli.ipynb 23
_quarto_yml="""ipynb-filters: [nbdev_filter]

project:
Expand Down Expand Up @@ -266,12 +273,15 @@ def refresh_quarto_yml():
yml=_quarto_yml.format(**vals)
p.write_text(yml)

# %% ../nbs/10_cli.ipynb 23
# %% ../nbs/10_cli.ipynb 24
@call_parse
def nbdev_new():
def nbdev_new(lib_name: str=None): # Package name (default: inferred from repo name)
"Create a new project from the current git repo"
override = locals()
from fastcore.net import urljson
config = prompt_user(**_fetch_from_git())
cfg = _mk_cfg(**override)
inferred = _fetch_from_git()
config = prompt_user(cfg, inferred)
# download and untar template, and optionally notebooks
tgnm = urljson('https://api.github.com/repos/fastai/nbdev-template/releases/latest')['tag_name']
FILES_URL = f"https:/fastai/nbdev-template/archive/{tgnm}.tar.gz"
Expand All @@ -294,12 +304,14 @@ def nbdev_new():
settings_path.write_text(settings)
refresh_quarto_yml()

# %% ../nbs/10_cli.ipynb 25
nbdev_export.__wrapped__()

# %% ../nbs/10_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 26
# %% ../nbs/10_cli.ipynb 27
def _doc_paths(path:str=None, doc_path:str=None):
cfg = get_config()
cfg_path = cfg.config_path
Expand All @@ -308,7 +320,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 27
# %% ../nbs/10_cli.ipynb 28
def _render_readme(path):
idx_path = path/config_key('readme_nb', path=False)
if not idx_path.exists(): return
Expand All @@ -324,7 +336,7 @@ def _render_readme(path):
finally:
if moved: (path/'sidebar.yml.bak').rename(yml_path)

# %% ../nbs/10_cli.ipynb 28
# %% ../nbs/10_cli.ipynb 29
@call_parse
def nbdev_readme(
path:str=None, # Path to notebooks
Expand All @@ -337,7 +349,7 @@ 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 29
# %% ../nbs/10_cli.ipynb 30
@call_parse
def nbdev_quarto(
path:str=None, # Path to notebooks
Expand Down
82 changes: 51 additions & 31 deletions nbs/10_cli.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"from execnb.nbio import *\n",
"from fastcore.utils import *\n",
"from fastcore.script import call_parse\n",
"from fastcore.style import S\n",
"from fastcore import shutil\n",
"\n",
"from urllib.error import HTTPError\n",
Expand Down Expand Up @@ -303,6 +304,17 @@
" with urlopen(url) as u: tarfile.open(mode='r:gz', fileobj=u).extractall(dest)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cbedb5a8",
"metadata": {},
"outputs": [],
"source": [
"#|export\n",
"def _mk_cfg(**kwargs): return {k: kwargs.get(k,None) for k in 'lib_name user branch author author_email keywords description repo'.split()}"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -343,27 +355,6 @@
" test_eq(_descrip, 'The fastai deep learning library')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b0720122-8fef-4999-8572-31ffc222d32f",
"metadata": {},
"outputs": [],
"source": [
"#|export\n",
"def prompt_user(**kwargs):\n",
" config_vals = kwargs\n",
" print('================ nbdev Configuration ================\\n')\n",
" for v in config_vals:\n",
" if not config_vals[v]:\n",
" print('\\nPlease enter information for the following field in settings.ini:')\n",
" inp = input(f'{v}: ')\n",
" config_vals[v] = inp\n",
" else: print(f\"{v}: '{config_vals[v]}' Automatically inferred from git.\")\n",
" print(f\"\\n`settings.ini` updated with configuration values.\")\n",
" return config_vals"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -374,17 +365,17 @@
"#|export\n",
"def _fetch_from_git(raise_err=False):\n",
" \"Get information for settings.ini from the user.\"\n",
" res = {}\n",
" try:\n",
" url = run('git config --get remote.origin.url')\n",
" author = run('git config --get user.name').strip()\n",
" email = run('git config --get user.email').strip()\n",
" owner,repo = repo_details(url)\n",
" branch,keywords,descrip = _get_info(owner=owner, repo=repo)\n",
" res['author'] = run('git config --get user.name').strip()\n",
" res['author_email'] = run('git config --get user.email').strip()\n",
" res['user'],res['repo'] = repo_details(url)\n",
" res['branch'],res['keywords'],res['description'] = _get_info(owner=res['user'], repo=res['repo'])\n",
" except OSError as e:\n",
" if raise_err: raise(e)\n",
" return dict(lib_name=None,user=None,branch=None,author=None,author_email=None,keywords=None,description=None,repo=None)\n",
" return dict(lib_name=repo.replace('-', '_'), user=owner, branch=branch, author=author, \n",
" author_email=email, keywords=keywords, description=descrip, repo=repo)"
" else: res['lib_name'] = res['repo'].replace('-','_')\n",
" return res"
]
},
{
Expand All @@ -398,6 +389,30 @@
"#test_eq(_fetch_from_git(raise_err=True)['lib_name'], 'nbdev')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "30bfe283",
"metadata": {},
"outputs": [],
"source": [
"#|export\n",
"def prompt_user(cfg, inferred):\n",
" \"Let user input values not in `cfg` or `inferred`.\"\n",
" print(S.dark_gray('# settings.ini'))\n",
" res = cfg.copy()\n",
" for k,v in cfg.items():\n",
" inf = inferred.get(k,None)\n",
" msg = S.light_blue(k) + ' = '\n",
" if v is None:\n",
" if inf is None: res[k] = input(S.dark_gray(f'# Please enter a value for {k}\\n')+msg)\n",
" else:\n",
" res[k] = inf\n",
" print(msg+res[k]+S.dark_gray(' # Automatically inferred from git'))\n",
" else: print(msg+str(v))\n",
" return res"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down Expand Up @@ -467,10 +482,13 @@
"source": [
"#|export\n",
"@call_parse\n",
"def nbdev_new():\n",
"def nbdev_new(lib_name: str=None): # Package name (default: inferred from repo name)\n",
" \"Create a new project from the current git repo\"\n",
" override = locals()\n",
" from fastcore.net import urljson\n",
" config = prompt_user(**_fetch_from_git())\n",
" cfg = _mk_cfg(**override)\n",
" inferred = _fetch_from_git()\n",
" config = prompt_user(cfg, inferred)\n",
" # download and untar template, and optionally notebooks\n",
" tgnm = urljson('https://api.github.com/repos/fastai/nbdev-template/releases/latest')['tag_name']\n",
" FILES_URL = f\"https:/fastai/nbdev-template/archive/{tgnm}.tar.gz\"\n",
Expand All @@ -491,7 +509,9 @@
" settings = settings_path.read_text()\n",
" settings = settings.format(**config)\n",
" settings_path.write_text(settings)\n",
" refresh_quarto_yml()"
" refresh_quarto_yml()\n",
"\n",
" nbdev_export.__wrapped__()"
]
},
{
Expand Down