Skip to content

Commit

Permalink
Implement --ignore, refactor Fs a little bit, etc.
Browse files Browse the repository at this point in the history
  • Loading branch information
arjun-menon committed Aug 3, 2024
1 parent bdd8401 commit 4dbb8d7
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 47 deletions.
38 changes: 18 additions & 20 deletions alteza/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
AltezaException,
Md,
NonMd,
FsCrawlResult,
Fs,
Fore,
Style,
Expand All @@ -42,7 +43,7 @@ class Args(Tap): # pyre-ignore[13]


class Content:
def __init__(self, args: Args, fs: Fs) -> None:
def __init__(self, args: Args, fs: FsCrawlResult) -> None:
self.inTemplate: bool = False
self.templateCache: Dict[str, str] = {}
self.seenTemplateLinks: Set[FileNode] = set()
Expand Down Expand Up @@ -328,11 +329,9 @@ def enterDir(newDir: str) -> Generator[None, None, None]:


class Engine:
# This class is just here to organize a bunch of related functions together.
# This class should never be instantiated, and most functions not called directly.
# Engine.generate(...) is called to write the output of a processed Content object.
# Similarly, Engine.run(args) is used to invoke Alteza overall.

# Engine.makeSite() is called to perform a full site generation.
# Engine.run() is used to invoke Alteza overall.
def __init__(self, args: Args) -> None:
self.args: Args = args
# Just copying & renaming a few args:
Expand All @@ -341,7 +340,7 @@ def __init__(self, args: Args) -> None:
self.outputDir: str = args.output
# Other instance variables:
self.shouldExit: bool = False
self.ignoreAbsPaths: List[str] = self.checkIgnorePaths(args)
self.setIgnoreAbsPaths(args)

@staticmethod
def generateMdContents(md: Md) -> None:
Expand Down Expand Up @@ -432,15 +431,15 @@ def resetOutputDir(self) -> None:
def processContent(self) -> Content:
with enterDir(self.contentDir):
print("Analyzing content directory...")
fs = Fs()
print(fs.nameRegistry)
content = Content(self.args, fs)
fsCrawlResult = Fs.crawl()
print(fsCrawlResult.nameRegistry)
content = Content(self.args, fsCrawlResult)
print("Processing...\n")
content.process()
print("\nSuccessfully completed processing.\n")

print("File Tree:")
print(fs.rootDir.displayDir())
print(fsCrawlResult.rootDir.displayDir())

return content

Expand All @@ -458,6 +457,15 @@ def makeSite(self) -> None:
# pylint: disable=consider-using-f-string
print("\nSite generation complete. Time elapsed: %.2f ms" % elapsedMilliseconds)

@staticmethod
def setIgnoreAbsPaths(args: Args) -> None:
Fs.ignoreAbsPaths = []
for somePath in args.ignore:
if os.path.exists(somePath):
Fs.ignoreAbsPaths.append(os.path.abspath(somePath))
else:
raise AltezaException(f"Path to ignore `{somePath}` does not exist.")

class WatchdogEventHandler(FileSystemEventHandler):
def __init__(self) -> None:
self.timeOfMostRecentEvent: Optional[int] = None
Expand Down Expand Up @@ -504,16 +512,6 @@ def signalHandler(sig: int, frame: Optional[types.FrameType]) -> None:
observer.stop()
observer.join()

@staticmethod
def checkIgnorePaths(args: Args) -> List[str]:
ignoreAbsPaths = []
for somePath in args.ignore:
if os.path.exists(somePath):
ignoreAbsPaths.append(os.path.abspath(somePath))
else:
raise AltezaException(f"Path to ignore `{somePath}` does not exist.")
return ignoreAbsPaths

def run(self) -> None:
self.makeSite()

Expand Down
59 changes: 33 additions & 26 deletions alteza/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import re
from collections import defaultdict
from dataclasses import dataclass
from datetime import date, datetime
from subprocess import check_output, CalledProcessError, STDOUT
from typing import (
Expand Down Expand Up @@ -55,13 +56,24 @@ def setNodeAsPublic(self) -> None:
self.shouldPublish = True

def makePublic(self) -> None:
Fs.runOnFsNodeAndAscendantNodes(self, lambda fsNode: fsNode.setNodeAsPublic())
self.runOnFsNodeAndAscendantNodes(self, lambda fsNode: fsNode.setNodeAsPublic())

def isParentGitRepo(self) -> bool:
if self.parent is None:
return DirNode.isPwdGitRepo()
return self.parent.isInGitRepo

@staticmethod
def runOnFsNodeAndAscendantNodes(
startingNode: "FsNode", fn: Callable[["FsNode"], None]
) -> None:
def walk(node: FsNode) -> None:
fn(node)
if node.parent is not None:
walk(node.parent)

walk(startingNode)


class FileNode(FsNode):
@staticmethod
Expand Down Expand Up @@ -153,8 +165,8 @@ def __init__(
self,
parent: Optional["DirNode"],
dirPath: str,
# shouldIgnore(name: str, isDir: bool) -> bool
shouldIgnore: Callable[[str, bool], bool],
# shouldIgnore(name: str, parentPath: str, isDir: bool) -> bool
shouldIgnore: Callable[[str, str, bool], bool],
) -> None:
_, subDirNames, fileNames = next(os.walk(dirPath))
dirPath = "" if dirPath == os.curdir else dirPath
Expand All @@ -163,12 +175,12 @@ def __init__(
self.files: List[FileNode] = [
FileNode.construct(self, dirPath, fileName)
for fileName in fileNames
if not shouldIgnore(fileName, False)
if not shouldIgnore(fileName, self.fullPath, False)
]
self.subDirs: List[DirNode] = [
DirNode(self, os.path.join(dirPath, subDirName), shouldIgnore)
for subDirName in subDirNames
if not shouldIgnore(subDirName, True)
if not shouldIgnore(subDirName, self.fullPath, True)
]

def getRectifiedName(self) -> str:
Expand Down Expand Up @@ -409,31 +421,27 @@ def __repr__(self) -> str:
)


@dataclass
class FsCrawlResult:
rootDir: DirNode
nameRegistry: NameRegistry


class Fs:
configFileName: str = "__config__.py"
ignoreAbsPaths: List[str] = []

@staticmethod
def readfile(file_path: str) -> str:
with open(file_path, "r", encoding="utf-8") as someFile:
return someFile.read()

@staticmethod
def runOnFsNodeAndAscendantNodes(
startingNode: FsNode, fn: Callable[[FsNode], None]
) -> None:
def walk(node: FsNode) -> None:
fn(node)
if node.parent is not None:
walk(node.parent)

walk(startingNode)

@staticmethod
def isHidden(name: str) -> bool:
return name.startswith(".")

@staticmethod
def defaultShouldIgnore(name: str, isDir: bool) -> bool:
def defaultShouldIgnore(name: str, parentPath: str, isDir: bool) -> bool:
# pylint: disable=unused-argument
if Fs.isHidden(name):
return True
Expand All @@ -444,6 +452,10 @@ def defaultShouldIgnore(name: str, isDir: bool) -> bool:
return True
if name != Fs.configFileName and fileExt == ".py":
return True
fullPath = os.path.abspath(os.path.join(parentPath, name))
for ignoreAbsPath in Fs.ignoreAbsPaths:
if fullPath in ignoreAbsPath:
return True
return False

@staticmethod
Expand All @@ -454,10 +466,10 @@ def defaultSkipForRegistry(name: str) -> bool:

@staticmethod
def crawl(
# Signature -- shouldIgnore(name: str, isDir: bool) -> bool
shouldIgnore: Callable[[str, bool], bool] = defaultShouldIgnore,
# Signature -- shouldIgnore(name: str, parentPath: str, isDir: bool) -> bool
shouldIgnore: Callable[[str, str, bool], bool] = defaultShouldIgnore,
skipForRegistry: Callable[[str], bool] = defaultSkipForRegistry,
) -> Tuple[DirNode, NameRegistry]:
) -> FsCrawlResult:
"""
Crawl the current directory. Construct & return an FsNode tree and NameRegistry.
"""
Expand All @@ -466,9 +478,4 @@ def crawl(
rootDir: DirNode = DirNode(None, dirPath, shouldIgnore)
nameRegistry = NameRegistry(rootDir, skipForRegistry)

return rootDir, nameRegistry

def __init__(self) -> None:
rootDir, nameRegistry = Fs.crawl()
self.rootDir: DirNode = rootDir
self.nameRegistry: NameRegistry = nameRegistry
return FsCrawlResult(rootDir, nameRegistry)
2 changes: 1 addition & 1 deletion build_test.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
python -m alteza --content test_content --output test_output --clear_output_dir --watch
python -m alteza --content test_content --output test_output --clear_output_dir --watch --ignore test_content/dirA

0 comments on commit 4dbb8d7

Please sign in to comment.