Coverage for /home/runner/work/coxbuild/coxbuild/src/coxbuild/extensions/__init__.py: 0%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

117 statements  

1import inspect 

2from abc import ABC, abstractmethod 

3from dataclasses import dataclass 

4from pathlib import Path 

5from types import ModuleType 

6from typing import Iterable 

7 

8import coxbuild 

9from coxbuild.configurations import Configuration, ConfigurationAccessor 

10from coxbuild.pipelines import PipelineHook 

11from coxbuild.services import EventHandler 

12from coxbuild.tasks import Task, TaskContext 

13 

14 

15@dataclass 

16class Extension: 

17 uri: str = "" 

18 name: str = "" 

19 description: str = "" 

20 version: str = "" 

21 hashcode: str = "" 

22 module: ModuleType | None = None 

23 

24 @property 

25 def tasks(self) -> Iterable[Task]: 

26 if not self.module: 

27 return 

28 for name, member in inspect.getmembers(self.module): 

29 if name.startswith("_"): 

30 continue 

31 

32 match member: 

33 case Task() as t: 

34 yield t 

35 case list() as l: 

36 for t in l: 

37 if isinstance(t, Task): 

38 yield t 

39 

40 @property 

41 def events(self) -> Iterable[EventHandler]: 

42 if not self.module: 

43 return 

44 for name, member in inspect.getmembers(self.module): 

45 if name.startswith("_"): 

46 continue 

47 

48 match member: 

49 case EventHandler() as t: 

50 yield t 

51 case list() as l: 

52 for t in l: 

53 if isinstance(t, EventHandler): 

54 yield t 

55 

56 @property 

57 def pipelineHooks(self) -> Iterable[PipelineHook]: 

58 if not self.module: 

59 return 

60 for name, member in inspect.getmembers(self.module): 

61 if name.startswith("_"): 

62 continue 

63 

64 match member: 

65 case PipelineHook() as t: 

66 yield t 

67 case list() as l: 

68 for t in l: 

69 if isinstance(t, PipelineHook): 

70 yield t 

71 

72 

73class ProjectSettings(ConfigurationAccessor): 

74 __configname__ = "project" 

75 

76 @property 

77 def name(self) -> str | None: 

78 return self.get("name") or coxbuild.get_working_directory().resolve().name 

79 

80 @name.setter 

81 def name(self, value: str): 

82 self.config["name"] = value 

83 

84 @property 

85 def version(self) -> str: 

86 """Build version.""" 

87 return self.get("version") or "" 

88 

89 @version.setter 

90 def version(self, value: str) -> None: 

91 self.config["version"] = value 

92 

93 @property 

94 def author(self) -> str: 

95 """Author name.""" 

96 return self.get("author") or "" 

97 

98 @author.setter 

99 def author(self, value: str) -> None: 

100 self.config["author"] = value 

101 

102 @property 

103 def description(self) -> str: 

104 """Project description.""" 

105 return self.get("description") or "" 

106 

107 @description.setter 

108 def description(self, value: str) -> None: 

109 self.config["description"] = value 

110 

111 @property 

112 def test(self) -> Path: 

113 """Path to test code.""" 

114 return (self.getPath("test") or coxbuild.get_working_directory().joinpath("test")).resolve() 

115 

116 @test.setter 

117 def test(self, value: Path) -> None: 

118 self.config["test"] = value.resolve() 

119 

120 @property 

121 def src(self) -> Path: 

122 """Source code path to build.""" 

123 return (self.getPath("src") or coxbuild.get_working_directory().joinpath("src")).resolve() 

124 

125 @src.setter 

126 def src(self, value: Path) -> None: 

127 self.config["src"] = value.resolve() 

128 

129 @property 

130 def package(self) -> Path: 

131 """Distribution path for building.""" 

132 return (self.getPath("package") or coxbuild.get_working_directory().joinpath("dist")).resolve() 

133 

134 @package.setter 

135 def package(self, value: Path) -> None: 

136 self.config["package"] = value.resolve() 

137 

138 @property 

139 def docs(self) -> Path: 

140 """Path to docs source.""" 

141 return (self.getPath("docs") or coxbuild.get_working_directory().joinpath("docs")).resolve() 

142 

143 @docs.setter 

144 def docs(self, value: Path) -> None: 

145 self.config["docs"] = value.resolve() 

146 

147 

148def withProject(task: Task) -> Task: 

149 """Decorator to add project argument to task context.""" 

150 def hook(context: TaskContext): 

151 if context.config: 

152 context.kwds.update(project=ProjectSettings(context.config)) 

153 

154 task.before(hook) 

155 return task