Skip to content

Commit 32411ae

Browse files
requested changes
1 parent 989f3c8 commit 32411ae

File tree

4 files changed

+52
-28
lines changed

4 files changed

+52
-28
lines changed

jupyterlab_git/__init__.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,19 @@ class JupyterLabGit(Configurable):
5151
config=True,
5252
)
5353

54+
output_cleaning_command = Unicode(
55+
"jupyter nbconvert",
56+
help="Notebook cleaning command. Configurable by server admin.",
57+
config=True,
58+
)
59+
60+
# Extra options to pass to the cleaning tool
61+
output_cleaning_options = Unicode(
62+
"--ClearOutputPreprocessor.enabled=True --inplace",
63+
help="Extra command-line options to pass to the cleaning tool.",
64+
config=True,
65+
)
66+
5467
@default("credential_helper")
5568
def _credential_helper_default(self):
5669
return "cache --timeout=3600"

jupyterlab_git/git.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,17 +1214,13 @@ async def strip_notebook_outputs(self, notebooks: list, repo_path: str):
12141214
full_path = os.path.join(repo_path, nb_path)
12151215

12161216
try:
1217-
# Clear outputs using nbconvert
1218-
subprocess.run(
1219-
[
1220-
"jupyter",
1221-
"nbconvert",
1222-
"--ClearOutputPreprocessor.enabled=True",
1223-
"--inplace",
1224-
full_path,
1225-
],
1226-
check=True,
1227-
)
1217+
cmd = shlex.split(self._config.output_cleaning_command)
1218+
options = shlex.split(self._config.output_cleaning_options)
1219+
1220+
full_cmd = cmd + options + [full_path]
1221+
1222+
# Run the cleaning command
1223+
subprocess.run(full_cmd, check=True)
12281224

12291225
# Re-stage the cleaned notebook
12301226
subprocess.run(["git", "-C", repo_path, "add", full_path], check=True)

schema/plugin.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,9 @@
8686
"clearOutputsBeforeCommit": {
8787
"type": "boolean",
8888
"title": "Clear outputs before commit",
89-
"description": "If true, notebook outputs will be cleared before committing.",
90-
"default": false
89+
"description": "If true, notebook outputs will be cleared before committing. If false, outputs are kept. If null, ask each time.",
90+
"default": null,
91+
"nullable": true
9192
}
9293
},
9394
"jupyter.lab.shortcuts": [

src/components/GitPanel.tsx

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { HistorySideBar } from './HistorySideBar';
3535
import { RebaseAction } from './RebaseAction';
3636
import { Toolbar } from './Toolbar';
3737
import { WarningBox } from './WarningBox';
38+
import { Widget } from '@lumino/widgets';
3839

3940
/**
4041
* Interface describing component properties.
@@ -810,22 +811,29 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
810811
const notebooksWithOutputs =
811812
await this.props.model.checkNotebooksForOutputs();
812813

813-
if (
814-
notebooksWithOutputs.length > 0 &&
815-
!this.props.settings.composite['clearOutputsBeforeCommit']
816-
) {
814+
const clearSetting =
815+
this.props.settings.composite['clearOutputsBeforeCommit'];
816+
if (notebooksWithOutputs.length > 0 && clearSetting == null) {
817+
const bodyWidget = new Widget();
818+
bodyWidget.node.innerHTML = `
819+
<div>
820+
<p>Clear all outputs before committing?</p>
821+
<label>
822+
<input type="checkbox" id="dontAskAgain" /> Save my preference
823+
</label>
824+
</div>
825+
`;
826+
817827
const dialog = new Dialog({
818828
title: this.props.trans.__('Notebook outputs detected'),
819-
body: `You are about to commit ${notebooksWithOutputs.length} notebook(s) with outputs.
820-
Would you like to clean them before committing? If you prefer not to be asked every time, you can enable the "Clear outputs before commit" option in the settings.`,
829+
body: bodyWidget,
821830
buttons: [
822831
Dialog.cancelButton({
823-
label: this.props.trans.__('Commit Anyway')
832+
label: this.props.trans.__('Keep Outputs & Commit')
824833
}),
825-
Dialog.okButton({
826-
label: this.props.trans.__('Clean & Commit')
827-
})
828-
]
834+
Dialog.okButton({ label: this.props.trans.__('Clean & Commit') })
835+
],
836+
defaultButton: 0
829837
});
830838

831839
const result = await dialog.launch();
@@ -835,9 +843,14 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
835843
return;
836844
}
837845
const accepted =
838-
typeof result.button.accept === 'boolean'
839-
? result.button.accept
840-
: result.button.label === this.props.trans.__('Clean & Commit');
846+
result.button.label === this.props.trans.__('Clean & Commit');
847+
const checkbox =
848+
bodyWidget.node.querySelector<HTMLInputElement>('#dontAskAgain');
849+
850+
// Remember the user’s choice if checkbox is checked
851+
if (checkbox?.checked) {
852+
this.props.settings.set('clearOutputsBeforeCommit', accepted);
853+
}
841854
if (accepted) {
842855
id = Notification.emit(
843856
this.props.trans.__('Cleaning notebook outputs…'),
@@ -847,7 +860,8 @@ export class GitPanel extends React.Component<IGitPanelProps, IGitPanelState> {
847860

848861
await this.props.model.stripNotebooksOutputs(notebooksWithOutputs);
849862
}
850-
} else if (this.props.settings.composite['clearOutputsBeforeCommit']) {
863+
} else if (clearSetting === true) {
864+
// Always clean before commit
851865
id = Notification.emit(
852866
this.props.trans.__('Cleaning notebook outputs…'),
853867
'in-progress',

0 commit comments

Comments
 (0)