or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bundle-management.mdcaching-versioning.mdcommand-line.mdconfiguration-loading.mdenvironment-configuration.mdfilter-system.mdframework-integration.mdindex.mdmerge-system.mdupdater-system.mdutilities.md

updater-system.mddocs/

0

# Updater System

1

2

The auto-rebuild system in webassets determines whether bundles need to be rebuilt by analyzing timestamps, bundle definitions, and dependencies. This system is optional and particularly useful during development and on small sites where rebuild checks on every request are acceptable.

3

4

## Capabilities

5

6

### Base Updater

7

8

Abstract base class for all updater implementations, using a registry pattern for automatic updater resolution.

9

10

```python { .api }

11

class BaseUpdater:

12

def needs_rebuild(self, bundle, ctx):

13

"""

14

Returns True if the given bundle needs to be rebuilt, False otherwise.

15

16

Args:

17

bundle: Bundle instance to check

18

ctx: Build context containing cache, manifest, and environment info

19

20

Returns:

21

bool: True if rebuild needed, False otherwise

22

"""

23

24

def build_done(self, bundle, ctx):

25

"""

26

Called once a bundle has been successfully built.

27

28

Args:

29

bundle: Bundle instance that was built

30

ctx: Build context

31

"""

32

```

33

34

### Bundle Definition Updater

35

36

Supports bundle definition cache update checks that detect when bundle configuration changes (source files added/removed, filters modified).

37

38

```python { .api }

39

class BundleDefUpdater(BaseUpdater):

40

def check_bundle_definition(self, bundle, ctx):

41

"""

42

Check if the bundle definition has changed since last build.

43

44

Args:

45

bundle: Bundle to check

46

ctx: Build context

47

48

Returns:

49

bool: True if bundle definition changed

50

"""

51

52

def needs_rebuild(self, bundle, ctx):

53

"""Check if rebuild needed based on bundle definition changes."""

54

55

def build_done(self, bundle, ctx):

56

"""Cache current bundle definition hash."""

57

```

58

59

### Timestamp Updater

60

61

Default updater that compares modification timestamps of source files, dependencies, and output files.

62

63

```python { .api }

64

class TimestampUpdater(BundleDefUpdater):

65

id = 'timestamp'

66

67

def check_timestamps(self, bundle, ctx, o_modified=None):

68

"""

69

Compare timestamps of all source files and dependencies against output.

70

71

Args:

72

bundle: Bundle to check

73

ctx: Build context

74

o_modified: Output file modification time (auto-detected if None)

75

76

Returns:

77

bool or SKIP_CACHE: True if rebuild needed, SKIP_CACHE if dependencies changed

78

"""

79

80

def needs_rebuild(self, bundle, ctx):

81

"""Check if rebuild needed based on timestamps and bundle definition."""

82

83

def build_done(self, bundle, ctx):

84

"""Reset resolved dependencies cache and update bundle definition."""

85

```

86

87

### Always Updater

88

89

Forces rebuilds on every check, useful for development or testing scenarios.

90

91

```python { .api }

92

class AlwaysUpdater(BaseUpdater):

93

id = 'always'

94

95

def needs_rebuild(self, bundle, ctx):

96

"""Always returns True to force rebuilds."""

97

```

98

99

### Updater Resolution

100

101

```python { .api }

102

def get_updater(updater_id):

103

"""

104

Resolve updater by string identifier.

105

106

Args:

107

updater_id: String identifier ('timestamp', 'always') or updater instance

108

109

Returns:

110

BaseUpdater: Updater instance

111

"""

112

```

113

114

## Constants

115

116

```python { .api }

117

SKIP_CACHE = object()

118

```

119

120

Special return value indicating that cache should not be used for rebuild. Used when bundle dependencies have changed, which would not normally cause a different cache key.

121

122

## Key Features

123

124

### Dependency Tracking

125

126

The updater system handles multiple types of dependencies:

127

128

- **Source files**: Direct bundle contents

129

- **Nested bundles**: Recursive timestamp checking

130

- **External dependencies**: Files referenced via `depends` argument

131

- **Filter dependencies**: Files discovered by filters (e.g., SASS imports)

132

133

### Bundle Definition Caching

134

135

Detects changes in bundle configuration by maintaining a hash-based cache:

136

137

- Tracks changes to source file lists

138

- Monitors filter modifications

139

- Detects option changes

140

- Requires environment cache to be configured

141

142

### Smart Rebuild Logic

143

144

The timestamp updater uses sophisticated logic:

145

146

- Handles missing output files gracefully

147

- Supports versioned output with placeholders

148

- Recurses through nested bundle hierarchies

149

- Manages dependency resolution and caching

150

- Returns `SKIP_CACHE` hint when dependencies change

151

152

## Usage Examples

153

154

### Basic Configuration

155

156

```python

157

from webassets import Environment

158

from webassets.updater import TimestampUpdater

159

160

env = Environment('./static', '/static')

161

env.updater = TimestampUpdater()

162

163

# Bundle will be checked for rebuild automatically

164

bundle = env['my_bundle']

165

if env.updater.needs_rebuild(bundle, env):

166

bundle.build()

167

```

168

169

### Custom Updater Implementation

170

171

```python

172

from webassets.updater import BaseUpdater

173

174

class CustomUpdater(BaseUpdater):

175

id = 'custom'

176

177

def needs_rebuild(self, bundle, ctx):

178

# Custom rebuild logic

179

return self.custom_check(bundle)

180

181

def build_done(self, bundle, ctx):

182

# Post-build actions

183

self.log_build(bundle)

184

185

# Register and use

186

env.updater = 'custom' # Resolves to CustomUpdater

187

```

188

189

### Development vs Production

190

191

```python

192

import os

193

from webassets.updater import TimestampUpdater, AlwaysUpdater

194

195

if os.environ.get('DEBUG'):

196

env.updater = AlwaysUpdater() # Always rebuild in development

197

else:

198

env.updater = TimestampUpdater() # Smart rebuilds in production

199

```