Skip to content

Commit f90a71d

Browse files
committed
feat: auto-generate contribute.md from nbs, re-add original contrib
1 parent d336eeb commit f90a71d

File tree

6 files changed

+139
-10
lines changed

6 files changed

+139
-10
lines changed

nbdev/_modidx.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,20 +257,22 @@
257257
'nbdev.quarto._SidebarYmlRemoved.__init__': ( 'api/quarto.html#_sidebarymlremoved.__init__',
258258
'nbdev/quarto.py'),
259259
'nbdev.quarto._copytree': ('api/quarto.html#_copytree', 'nbdev/quarto.py'),
260+
'nbdev.quarto._doc_mtime_not_older': ('api/quarto.html#_doc_mtime_not_older', 'nbdev/quarto.py'),
260261
'nbdev.quarto._ensure_quarto': ('api/quarto.html#_ensure_quarto', 'nbdev/quarto.py'),
261262
'nbdev.quarto._install_linux': ('api/quarto.html#_install_linux', 'nbdev/quarto.py'),
262263
'nbdev.quarto._install_mac': ('api/quarto.html#_install_mac', 'nbdev/quarto.py'),
263264
'nbdev.quarto._nbglob_docs': ('api/quarto.html#_nbglob_docs', 'nbdev/quarto.py'),
264265
'nbdev.quarto._pre': ('api/quarto.html#_pre', 'nbdev/quarto.py'),
265266
'nbdev.quarto._pre_docs': ('api/quarto.html#_pre_docs', 'nbdev/quarto.py'),
266-
'nbdev.quarto._readme_mtime_not_older': ('api/quarto.html#_readme_mtime_not_older', 'nbdev/quarto.py'),
267267
'nbdev.quarto._recursive_parser': ('api/quarto.html#_recursive_parser', 'nbdev/quarto.py'),
268+
'nbdev.quarto._save_cached_contributing': ('api/quarto.html#_save_cached_contributing', 'nbdev/quarto.py'),
268269
'nbdev.quarto._save_cached_readme': ('api/quarto.html#_save_cached_readme', 'nbdev/quarto.py'),
269270
'nbdev.quarto._sort': ('api/quarto.html#_sort', 'nbdev/quarto.py'),
270271
'nbdev.quarto._sprun': ('api/quarto.html#_sprun', 'nbdev/quarto.py'),
271272
'nbdev.quarto.fs_watchdog': ('api/quarto.html#fs_watchdog', 'nbdev/quarto.py'),
272273
'nbdev.quarto.install': ('api/quarto.html#install', 'nbdev/quarto.py'),
273274
'nbdev.quarto.install_quarto': ('api/quarto.html#install_quarto', 'nbdev/quarto.py'),
275+
'nbdev.quarto.nbdev_contributing': ('api/quarto.html#nbdev_contributing', 'nbdev/quarto.py'),
274276
'nbdev.quarto.nbdev_docs': ('api/quarto.html#nbdev_docs', 'nbdev/quarto.py'),
275277
'nbdev.quarto.nbdev_preview': ('api/quarto.html#nbdev_preview', 'nbdev/quarto.py'),
276278
'nbdev.quarto.nbdev_proc_nbs': ('api/quarto.html#nbdev_proc_nbs', 'nbdev/quarto.py'),

nbdev/cli.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from .doclinks import *
1414
from .test import *
1515
from .clean import *
16-
from .quarto import nbdev_readme, refresh_quarto_yml, fs_watchdog
16+
from .quarto import nbdev_readme, nbdev_contributing, refresh_quarto_yml, fs_watchdog
1717
from .export import nb_export
1818
from .frontmatter import FrontmatterProc
1919

@@ -121,6 +121,7 @@ def nbdev_new(**kwargs):
121121
refresh_quarto_yml()
122122
nbdev_export.__wrapped__()
123123
nbdev_readme.__wrapped__()
124+
nbdev_contributing.__wrapped__()
124125

125126
# %% ../nbs/api/13_cli.ipynb
126127
mapping = {

nbdev/quarto.py

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
# %% auto 0
2323
__all__ = ['BASE_QUARTO_URL', 'install_quarto', 'install', 'IndentDumper', 'nbdev_sidebar', 'refresh_quarto_yml',
24-
'nbdev_proc_nbs', 'nbdev_readme', 'nbdev_docs', 'prepare', 'fs_watchdog', 'nbdev_preview']
24+
'nbdev_proc_nbs', 'nbdev_readme', 'nbdev_contributing', 'nbdev_docs', 'prepare', 'fs_watchdog',
25+
'nbdev_preview']
2526

2627
# %% ../nbs/api/14_quarto.ipynb
2728
def _sprun(cmd):
@@ -214,7 +215,7 @@ def nbdev_proc_nbs(**kwargs):
214215
_pre_docs(**kwargs)[0]
215216

216217
# %% ../nbs/api/14_quarto.ipynb
217-
def _readme_mtime_not_older(readme_path, readme_nb_path):
218+
def _doc_mtime_not_older(readme_path, readme_nb_path):
218219
if not readme_nb_path.exists():
219220
print(f"Could not find {readme_nb_path}")
220221
return True
@@ -259,14 +260,66 @@ def nbdev_readme(
259260
"Create README.md from readme_nb (index.ipynb by default)"
260261
cfg = get_config()
261262
path = Path(path) if path else cfg.nbs_path
262-
if chk_time and _readme_mtime_not_older(cfg.config_path/'README.md', path/cfg.readme_nb): return
263+
if chk_time and _doc_mtime_not_older(cfg.config_path/'README.md', path/cfg.readme_nb): return
263264

264265
with _SidebarYmlRemoved(path): # to avoid rendering whole website
265266
cache = proc_nbs(path)
266267
_sprun(f'cd "{cache}" && quarto render "{cache/cfg.readme_nb}" -o README.md -t gfm --no-execute')
267268

268269
_save_cached_readme(cache, cfg)
269270

271+
# %% ../nbs/api/14_quarto.ipynb
272+
def _save_cached_contributing(cache, cfg, contrib_nb):
273+
"Move CONTRIBUTING.md (and any `_files` assets) from the Quarto build cache to the repo root."
274+
tmp_doc_path = cache / cfg.doc_path.name
275+
contrib_file = tmp_doc_path / 'CONTRIBUTING.md'
276+
if contrib_file.exists():
277+
final_path = cfg.config_path / 'CONTRIBUTING.md'
278+
if final_path.exists(): final_path.unlink() # Py3.7 doesn't have missing_ok
279+
move(contrib_file, final_path)
280+
# Move any supporting files folder
281+
assets_folder = tmp_doc_path / (Path(contrib_nb).stem + '_files')
282+
if assets_folder.exists():
283+
_copytree(assets_folder, cfg.config_path / assets_folder.name)
284+
285+
# %% ../nbs/api/14_quarto.ipynb
286+
@call_parse
287+
def nbdev_contributing(
288+
path:str=None, # Path to notebooks (defaults to nbs_path)
289+
chk_time:bool=False # Only build if out-of-date
290+
):
291+
"""
292+
Create CONTRIBUTING.md from contributing_nb (defaults to 'contributing.ipynb' if present).
293+
Skips if the file doesn't exist.
294+
"""
295+
cfg = get_config()
296+
path = Path(path) if path else cfg.nbs_path
297+
298+
# Decide which notebook is your "contributing" NB (you can hardcode or add to settings.ini)
299+
contrib_nb_name = cfg.get('contributing_nb', 'contributing.ipynb')
300+
contrib_nb_path = path / contrib_nb_name
301+
302+
contrib_md = cfg.config_path / 'CONTRIBUTING.md'
303+
304+
# If out of date check is requested, skip if up-to-date or missing
305+
if chk_time and _doc_mtime_not_older(contrib_md, contrib_nb_path):
306+
return
307+
308+
# If there's no contributing notebook, do nothing
309+
if not contrib_nb_path.exists():
310+
return
311+
312+
# Temporarily remove sidebar.yml so Quarto doesn't try to build the entire site
313+
with _SidebarYmlRemoved(path):
314+
cache = proc_nbs(path)
315+
316+
# Render a single .ipynb -> .md in GFM
317+
_sprun(f'cd "{cache}" && quarto render "{cache/contrib_nb_name}" -o CONTRIBUTING.md -t gfm --no-execute')
318+
319+
# Copy the newly created CONTRIBUTING.md and _files folder back to the repo root
320+
_save_cached_contributing(cache, cfg, contrib_nb_name)
321+
322+
270323
# %% ../nbs/api/14_quarto.ipynb
271324
@call_parse
272325
@delegates(_nbglob_docs)
@@ -277,6 +330,7 @@ def nbdev_docs(
277330
"Create Quarto docs and README.md"
278331
cache,cfg,path = _pre_docs(path, n_workers=n_workers, **kwargs)
279332
nbdev_readme.__wrapped__(path=path, chk_time=True)
333+
nbdev_contributing.__wrapped__(path=path, chk_time=True)
280334
_sprun(f'cd "{cache}" && quarto render --no-cache')
281335
shutil.rmtree(cfg.doc_path, ignore_errors=True)
282336
move(cache/cfg.doc_path.name, cfg.config_path)
@@ -291,6 +345,7 @@ def prepare():
291345
nbdev.clean.nbdev_clean.__wrapped__()
292346
refresh_quarto_yml()
293347
nbdev_readme.__wrapped__(chk_time=True)
348+
nbdev_contributing.__wrapped__(chk_time=True)
294349

295350
# %% ../nbs/api/14_quarto.ipynb
296351
@contextmanager

nbs/api/13_cli.ipynb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"from nbdev.doclinks import *\n",
3939
"from nbdev.test import *\n",
4040
"from nbdev.clean import *\n",
41-
"from nbdev.quarto import nbdev_readme, refresh_quarto_yml, fs_watchdog\n",
41+
"from nbdev.quarto import nbdev_readme, nbdev_contributing, refresh_quarto_yml, fs_watchdog\n",
4242
"from nbdev.export import nb_export\n",
4343
"from nbdev.frontmatter import FrontmatterProc\n",
4444
"\n",
@@ -222,7 +222,8 @@
222222
"\n",
223223
" refresh_quarto_yml()\n",
224224
" nbdev_export.__wrapped__()\n",
225-
" nbdev_readme.__wrapped__()"
225+
" nbdev_readme.__wrapped__()\n",
226+
" nbdev_contributing.__wrapped__()"
226227
]
227228
},
228229
{

nbs/api/14_quarto.ipynb

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@
404404
"outputs": [],
405405
"source": [
406406
"#|export\n",
407-
"def _readme_mtime_not_older(readme_path, readme_nb_path):\n",
407+
"def _doc_mtime_not_older(readme_path, readme_nb_path):\n",
408408
" if not readme_nb_path.exists():\n",
409409
" print(f\"Could not find {readme_nb_path}\")\n",
410410
" return True\n",
@@ -482,7 +482,7 @@
482482
" \"Create README.md from readme_nb (index.ipynb by default)\"\n",
483483
" cfg = get_config()\n",
484484
" path = Path(path) if path else cfg.nbs_path\n",
485-
" if chk_time and _readme_mtime_not_older(cfg.config_path/'README.md', path/cfg.readme_nb): return\n",
485+
" if chk_time and _doc_mtime_not_older(cfg.config_path/'README.md', path/cfg.readme_nb): return\n",
486486
"\n",
487487
" with _SidebarYmlRemoved(path): # to avoid rendering whole website\n",
488488
" cache = proc_nbs(path)\n",
@@ -510,6 +510,73 @@
510510
"# nbdev_readme.__wrapped__(chk_time=False)"
511511
]
512512
},
513+
{
514+
"cell_type": "code",
515+
"execution_count": null,
516+
"id": "ef3f1e1f",
517+
"metadata": {},
518+
"outputs": [],
519+
"source": [
520+
"#|export\n",
521+
"def _save_cached_contributing(cache, cfg, contrib_nb):\n",
522+
" \"Move CONTRIBUTING.md (and any `_files` assets) from the Quarto build cache to the repo root.\"\n",
523+
" tmp_doc_path = cache / cfg.doc_path.name\n",
524+
" contrib_file = tmp_doc_path / 'CONTRIBUTING.md'\n",
525+
" if contrib_file.exists():\n",
526+
" final_path = cfg.config_path / 'CONTRIBUTING.md'\n",
527+
" if final_path.exists(): final_path.unlink() # Py3.7 doesn't have missing_ok\n",
528+
" move(contrib_file, final_path)\n",
529+
" # Move any supporting files folder\n",
530+
" assets_folder = tmp_doc_path / (Path(contrib_nb).stem + '_files')\n",
531+
" if assets_folder.exists():\n",
532+
" _copytree(assets_folder, cfg.config_path / assets_folder.name)"
533+
]
534+
},
535+
{
536+
"cell_type": "code",
537+
"execution_count": null,
538+
"id": "729a0fa1",
539+
"metadata": {},
540+
"outputs": [],
541+
"source": [
542+
"#|export\n",
543+
"@call_parse\n",
544+
"def nbdev_contributing(\n",
545+
" path:str=None, # Path to notebooks (defaults to nbs_path)\n",
546+
" chk_time:bool=False # Only build if out-of-date\n",
547+
"):\n",
548+
" \"\"\"\n",
549+
" Create CONTRIBUTING.md from contributing_nb (defaults to 'contributing.ipynb' if present).\n",
550+
" Skips if the file doesn't exist.\n",
551+
" \"\"\"\n",
552+
" cfg = get_config()\n",
553+
" path = Path(path) if path else cfg.nbs_path\n",
554+
" \n",
555+
" # Decide which notebook is your \"contributing\" NB (you can hardcode or add to settings.ini)\n",
556+
" contrib_nb_name = cfg.get('contributing_nb', 'contributing.ipynb')\n",
557+
" contrib_nb_path = path / contrib_nb_name\n",
558+
" \n",
559+
" contrib_md = cfg.config_path / 'CONTRIBUTING.md'\n",
560+
" \n",
561+
" # If out of date check is requested, skip if up-to-date or missing\n",
562+
" if chk_time and _doc_mtime_not_older(contrib_md, contrib_nb_path):\n",
563+
" return\n",
564+
" \n",
565+
" # If there's no contributing notebook, do nothing\n",
566+
" if not contrib_nb_path.exists():\n",
567+
" return\n",
568+
" \n",
569+
" # Temporarily remove sidebar.yml so Quarto doesn't try to build the entire site\n",
570+
" with _SidebarYmlRemoved(path):\n",
571+
" cache = proc_nbs(path)\n",
572+
" \n",
573+
" # Render a single .ipynb -> .md in GFM\n",
574+
" _sprun(f'cd \"{cache}\" && quarto render \"{cache/contrib_nb_name}\" -o CONTRIBUTING.md -t gfm --no-execute')\n",
575+
" \n",
576+
" # Copy the newly created CONTRIBUTING.md and _files folder back to the repo root\n",
577+
" _save_cached_contributing(cache, cfg, contrib_nb_name)\n"
578+
]
579+
},
513580
{
514581
"cell_type": "code",
515582
"execution_count": null,
@@ -527,6 +594,7 @@
527594
" \"Create Quarto docs and README.md\"\n",
528595
" cache,cfg,path = _pre_docs(path, n_workers=n_workers, **kwargs)\n",
529596
" nbdev_readme.__wrapped__(path=path, chk_time=True)\n",
597+
" nbdev_contributing.__wrapped__(path=path, chk_time=True)\n",
530598
" _sprun(f'cd \"{cache}\" && quarto render --no-cache')\n",
531599
" shutil.rmtree(cfg.doc_path, ignore_errors=True)\n",
532600
" move(cache/cfg.doc_path.name, cfg.config_path)"
@@ -559,7 +627,8 @@
559627
" nbdev.test.nbdev_test.__wrapped__()\n",
560628
" nbdev.clean.nbdev_clean.__wrapped__()\n",
561629
" refresh_quarto_yml()\n",
562-
" nbdev_readme.__wrapped__(chk_time=True)"
630+
" nbdev_readme.__wrapped__(chk_time=True)\n",
631+
" nbdev_contributing.__wrapped__(chk_time=True)"
563632
]
564633
},
565634
{

settings.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ console_scripts = nbdev_create_config=nbdev.config:nbdev_create_config
4040
nbdev_preview=nbdev.quarto:nbdev_preview
4141
nbdev_prepare=nbdev.quarto:prepare
4242
nbdev_readme=nbdev.quarto:nbdev_readme
43+
nbdev_contributing=nbdev.quarto:nbdev_contributing
4344
nbdev_release_gh=nbdev.release:release_gh
4445
nbdev_release_git=nbdev.release:release_git
4546
nbdev_changelog=nbdev.release:changelog

0 commit comments

Comments
 (0)