Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
CommentTracker.py (#26 closes #25)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg authored Mar 6, 2024
2 parents 5e98465 + 6c28563 commit f8f51a4
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 0 deletions.
87 changes: 87 additions & 0 deletions python/selfie-lib/selfie_lib/CommentTracker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from typing import Dict, Iterable, Tuple
from enum import Enum, auto
import threading
from selfie_lib.TypedPath import TypedPath
from selfie_lib.Slice import Slice


# Placeholder implementations for CallStack, SnapshotFileLayout, and FS
class CallStack:
pass


class SnapshotFileLayout:
def sourcePathForCall(self, location) -> "TypedPath":
# Placeholder return or raise NotImplementedError
raise NotImplementedError("sourcePathForCall is not implemented")


class WritableComment(Enum):
NO_COMMENT = auto()
ONCE = auto()
FOREVER = auto()

@property
def writable(self) -> bool:
return self != WritableComment.NO_COMMENT


class CommentTracker:
def __init__(self):
self.cache: Dict[TypedPath, WritableComment] = {}
self.lock = threading.Lock()

def pathsWithOnce(self) -> Iterable[TypedPath]:
with self.lock:
return [
path
for path, comment in self.cache.items()
if comment == WritableComment.ONCE
]

def hasWritableComment(self, call: CallStack, layout: SnapshotFileLayout) -> bool:
path = layout.sourcePathForCall(call)
with self.lock:
if path in self.cache:
comment = self.cache[path]
if comment.writable:
return True
else:
return False
else:
new_comment, _ = self.__commentAndLine(path)
self.cache[path] = new_comment
return new_comment.writable

@staticmethod
def commentString(typedPath: TypedPath) -> Tuple[str, int]:
comment, line = CommentTracker.__commentAndLine(typedPath)
if comment == WritableComment.NO_COMMENT:
raise ValueError("No writable comment found")
elif comment == WritableComment.ONCE:
return ("//selfieonce", line)
elif comment == WritableComment.FOREVER:
return ("//SELFIEWRITE", line)
else:
raise ValueError("Invalid comment type")

@staticmethod
def __commentAndLine(typedPath: TypedPath) -> Tuple[WritableComment, int]:
with open(typedPath.absolute_path, "r") as file:
content = Slice(file.read())
for comment_str in [
"//selfieonce",
"// selfieonce",
"//SELFIEWRITE",
"// SELFIEWRITE",
]:
index = content.indexOf(comment_str)
if index != -1:
lineNumber = content.baseLineAtOffset(index)
comment = (
WritableComment.ONCE
if "once" in comment_str
else WritableComment.FOREVER
)
return (comment, lineNumber)
return (WritableComment.NO_COMMENT, -1)
3 changes: 3 additions & 0 deletions python/selfie-lib/selfie_lib/TypedPath.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ class TypedPath:
def __init__(self, absolute_path: str):
self.absolute_path = absolute_path

def __hash__(self):
return hash(self.absolute_path)

@property
def name(self) -> str:
if self.absolute_path.endswith("/"):
Expand Down

0 comments on commit f8f51a4

Please sign in to comment.