Skip to content

Commit

Permalink
Fix PR requests for gitignore bug
Browse files Browse the repository at this point in the history
  • Loading branch information
kentarolim10 committed Oct 30, 2023
1 parent 6eac31d commit a09953d
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 36 deletions.
21 changes: 8 additions & 13 deletions jupyterlab_git/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -1681,7 +1681,7 @@ async def remote_remove(self, path, name):

return response

async def read_file(self, path):
def read_file(self, path):
"""
Reads file content located at path and returns it as a string
Expand All @@ -1690,12 +1690,10 @@ async def read_file(self, path):
"""
try:
file = pathlib.Path(path)
if file.stat().st_size > 0:
content = file.read_text()
return content
return ""
content = file.read_text()
return {"code": 0, "content": content}
except BaseException as error:
return ""
return {"code": -1, "content": ""}

async def ensure_gitignore(self, path):
"""Handle call to ensure .gitignore file exists and the
Expand Down Expand Up @@ -1737,7 +1735,7 @@ async def ignore(self, path, file_path):
return {"code": -1, "message": str(error)}
return {"code": 0}

async def writeGitignore(self, path, content):
async def write_gitignore(self, path, content):
"""
Handle call to overwrite .gitignore.
Takes the .gitignore file and clears its previous contents
Expand All @@ -1753,12 +1751,9 @@ async def writeGitignore(self, path, content):
if res["code"] != 0:
return res
gitignore = pathlib.Path(path) / ".gitignore"
with gitignore.open("a") as f:
f.truncate(0)
f.seek(0)
f.write(content)
if content[-1] != "\n":
f.write("\n")
if content and content[-1] != "\n":
content += "\n"
gitignore.write_text(content)
except BaseException as error:
return {"code": -1, "message": str(error)}
return {"code": 0}
Expand Down
17 changes: 12 additions & 5 deletions jupyterlab_git/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,17 @@ class GitIgnoreHandler(GitHandler):
Handler to manage .gitignore
"""

@tornado.web.authenticated
async def get(self, path: str = ""):
"""
GET read content in .gitignore
"""
local_path = self.url2localpath(path)
body = self.git.read_file(local_path + "/.gitignore")
if body["code"] != 0:
self.set_status(500)
self.finish(json.dumps(body))

@tornado.web.authenticated
async def post(self, path: str = ""):
"""
Expand All @@ -821,7 +832,7 @@ async def post(self, path: str = ""):
content = data.get("content", None)
use_extension = data.get("use_extension", False)
if content:
body = await self.git.writeGitignore(local_path, content)
body = await self.git.write_gitignore(local_path, content)
elif file_path:
if use_extension:
suffixes = Path(file_path).suffixes
Expand All @@ -830,10 +841,6 @@ async def post(self, path: str = ""):
body = await self.git.ignore(local_path, file_path)
else:
body = await self.git.ensure_gitignore(local_path)
if not self.serverapp.contents_manager.allow_hidden and not content:
self.set_status(403, "hidden files cannot be accessed")
body["content"] = await self.git.read_file(local_path + "/.gitignore")

if body["code"] != 0:
self.set_status(500)
self.finish(json.dumps(body))
Expand Down
31 changes: 20 additions & 11 deletions src/commandsAndMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,10 @@ export function addCommands(

async function showGitignore(error: any) {
const model = new CodeEditor.Model({});
const id = 'git-ignore';
//
const repoPath = gitModel.getRelativeFilePath();
const id = repoPath + '/.git-ignore';
const contentData = await gitModel.readGitIgnore();

const gitIgnoreWidget = find(shell.widgets(), shellWidget => {
if (shellWidget.id === id) {
return true;
Expand All @@ -319,7 +321,7 @@ export function addCommands(
shell.activateById(id);
return;
}
model.sharedModel.setSource(error.content ? error.content : '');
model.sharedModel.setSource(contentData.content ? contentData.content : '');
const editor = new CodeEditorWrapper({
factory: editorServices.factoryService.newDocumentEditor,
model: model
Expand All @@ -328,13 +330,15 @@ export function addCommands(
editor.disposed.connect(() => {
model.dispose();
});
const preview = new PreviewMainAreaWidget({
const preview = new MainAreaWidget({
content: editor
});

preview.title.label = '.gitignore';
preview.id = id;
preview.title.icon = gitIcon;
preview.title.closable = true;
preview.title.caption = repoPath + '/.gitignore';
const saveButton = new ToolbarButton({
icon: saveIcon,
onClick: async () => {
Expand Down Expand Up @@ -364,7 +368,10 @@ export function addCommands(
}

/* Helper: Show gitignore hidden file */
async function showGitignoreHiddenFile(error: any) {
async function showGitignoreHiddenFile(error: any, hidePrompt: boolean) {
if (hidePrompt) {
return showGitignore(error);
}
const result = await showDialog({
title: trans.__('Warning: The .gitignore file is a hidden file.'),
body: (
Expand Down Expand Up @@ -417,11 +424,10 @@ export function addCommands(
await gitModel.ensureGitignore();
} catch (error: any) {
if (error?.name === 'hiddenFile') {
if (settings.composite['hideHiddenFileWarning']) {
await showGitignore(error);
} else {
await showGitignoreHiddenFile(error);
}
await showGitignoreHiddenFile(
error,
settings.composite['hideHiddenFileWarning'] as boolean
);
}
}
}
Expand Down Expand Up @@ -1574,7 +1580,10 @@ export function addCommands(
await gitModel.ignore(file.to, false);
} catch (error: any) {
if (error?.name === 'hiddenFile') {
await showGitignoreHiddenFile(error);
await showGitignoreHiddenFile(
error,
settings.composite['hideHiddenFileWarning'] as boolean
);
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ export async function requestAPI<T>(
if (!response.ok) {
if (isJSON) {
const { message, traceback, ...json } = data;
if (response.status === 403) {
throw new Git.HiddenFile(data.content);
}
throw new Git.GitResponseError(
response,
message ||
Expand Down
40 changes: 39 additions & 1 deletion src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { AUTH_ERROR_MESSAGES, requestAPI } from './git';
import { TaskHandler } from './taskhandler';
import { Git, IGitExtension } from './tokens';
import { decodeStage } from './utils';
import { ServerConnection } from '@jupyterlab/services';

// Default refresh interval (in milliseconds) for polling the current Git status (NOTE: this value should be the same value as in the plugin settings schema):
const DEFAULT_REFRESH_INTERVAL = 3000; // ms
Expand Down Expand Up @@ -866,10 +867,38 @@ export class GitExtension implements IGitExtension {
const path = await this._getPathRepository();

await requestAPI(URLExt.join(path, 'ignore'), 'POST', {});
try {
await this._docmanager.services.contents.get(`${path}/.gitignore`, {
content: false
});
} catch (e) {
// If the previous request failed with a 404 error, it means hidden file cannot be accessed
if ((e as ServerConnection.ResponseError).response?.status === 404) {
throw new Git.HiddenFile();
}
}
this._openGitignore();
await this.refreshStatus();
}

/**
* Reads content of .gitignore file
*
* @throws {Git.NotInRepository} If the current path is not a Git repository
* @throws {Git.GitResponseError} If the server response is not ok
* @throws {ServerConnection.NetworkError} If the request cannot be made
*/
async readGitIgnore(): Promise<{ code: number; content: string }> {
const path = await this._getPathRepository();

const res = (await requestAPI(URLExt.join(path, 'ignore'), 'GET')) as {
code: number;
content: string;
};
await this.refreshStatus();
return res;
}

/**
* Overwrites content onto .gitignore file
*
Expand Down Expand Up @@ -947,7 +976,16 @@ export class GitExtension implements IGitExtension {
file_path: filePath,
use_extension: useExtension
});

try {
await this._docmanager.services.contents.get(`${path}/.gitignore`, {
content: false
});
} catch (e) {
// If the previous request failed with a 404 error, it means hidden file cannot be accessed
if ((e as ServerConnection.ResponseError).response?.status === 404) {
throw new Git.HiddenFile();
}
}
this._openGitignore();
await this.refreshStatus();
}
Expand Down
4 changes: 1 addition & 3 deletions src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1301,12 +1301,10 @@ export namespace Git {
}

export class HiddenFile extends Error {
content: string;
constructor(content: string) {
constructor() {
super('File is hidden');
this.name = 'hiddenFile';
this.message = 'File is hidden and cannot be accessed.';
this.content = content;
}
}

Expand Down

0 comments on commit a09953d

Please sign in to comment.