Tutorial 3 - Changing Glob Patterns
Control which files are processed vs copied
Tutorial 3: Changing Glob Patterns
Control which files are processed vs copied. This is essential for projects with mixed content types.
Why Different GlobTypes Matter
Not all files should be processed the same way:
- Text files (
.md,.ts,.json) - Need variable substitution withGlobType.Template - Binary files (
.png,.jpg,.pdf) - Must be copied as-is withGlobType.Copy - Processor output - When chaining processors, use
GlobType.Processorto read from previous processor
Using GlobType.Template on binary files corrupts them because the processor attempts variable substitution on binary data.
GlobType Options
| Type | Behavior | Data Source |
|---|---|---|
GlobType.Template | Process with variable substitution | Reads from template's blob |
GlobType.Copy | Copy without processing | Reads from template's blob |
GlobType.Processor | Pass through for chaining | Reads from processor's output |
GlobType.Template and GlobType.Copy both read from the template's blob (your template files). GlobType.Processor is used when chaining multiple processors together, reading from the previous processor's output.
Multiple File Groups
Use multiple file entries with different glob patterns:
files: [// Process text files with variable substitution{ root: 'templates', glob: '**/*.md', exclude: [], type: GlobType.Template },{ root: 'templates', glob: '**/*.txt', exclude: [], type: GlobType.Template },{ root: 'templates', glob: '**/*.json', exclude: [], type: GlobType.Template },// Copy binary files without processing{ root: 'templates', glob: '**/*.png', exclude: [], type: GlobType.Copy },{ root: 'templates', glob: '**/*.jpg', exclude: [], type: GlobType.Copy },// Copy static assets{ root: 'static', glob: '**/*', exclude: [], type: GlobType.Copy }]
files = [# Process text files with variable substitutionCyanGlob(root="templates", glob="**/*.md", exclude=[], type=GlobType.TEMPLATE),CyanGlob(root="templates", glob="**/*.txt", exclude=[], type=GlobType.TEMPLATE),CyanGlob(root="templates", glob="**/*.json", exclude=[], type=GlobType.TEMPLATE),# Copy binary files without processingCyanGlob(root="templates", glob="**/*.png", exclude=[], type=GlobType.COPY),CyanGlob(root="templates", glob="**/*.jpg", exclude=[], type=GlobType.COPY),# Copy static assetsCyanGlob(root="static", glob="**/*", exclude=[], type=GlobType.COPY),]
Files =[// Process text files with variable substitutionnew CyanGlob { Root = "templates", Glob = "**/*.md", Exclude = [], Type = GlobType.Template },new CyanGlob { Root = "templates", Glob = "**/*.txt", Exclude = [], Type = GlobType.Template },new CyanGlob { Root = "templates", Glob = "**/*.json", Exclude = [], Type = GlobType.Template },// Copy binary files without processingnew CyanGlob { Root = "templates", Glob = "**/*.png", Exclude = [], Type = GlobType.Copy },new CyanGlob { Root = "templates", Glob = "**/*.jpg", Exclude = [], Type = GlobType.Copy },// Copy static assetsnew CyanGlob { Root = "static", Glob = "**/*", Exclude = [], Type = GlobType.Copy },]
Complete Example
Building on Tutorial 2, update your template to handle mixed file types:
Update cyan/index.ts:
import { StartTemplateWithLambda, GlobType } from '@atomicloud/cyan-sdk';StartTemplateWithLambda(async (i, d) => {return {processors: [{name: 'cyan/default',files: [+// Template files - variable substitution{ root: 'templates', glob: '**/*.md', exclude: [], type: GlobType.Template },-{ root: 'template', glob: '**/*', exclude: [], type: GlobType.Template },+{ root: 'templates', glob: '**/*.yaml', exclude: [], type: GlobType.Template },{ root: 'templates', glob: '**/*.json', exclude: [], type: GlobType.Template },{ root: 'templates', glob: '**/*.ts', exclude: [], type: GlobType.Template },// Binary files - copy only (never process these!){ root: 'templates', glob: '**/*.png', exclude: [], type: GlobType.Copy },{ root: 'templates', glob: '**/*.ico', exclude: [], type: GlobType.Copy },// Static directory - copy all{ root: 'static', glob: '**/*', exclude: [], type: GlobType.Copy }],config: {vars: {name: 'my-project',author: 'Developer'}}}],plugins: []};});
Update cyan/index.py:
from cyanprintsdk import start_template_with_fn, GlobTypefrom cyanprintsdk.domain.core.cyan import Cyan, CyanProcessor, CyanGlobasync def my_template(i, d):return Cyan(processors=[CyanProcessor(name="cyan/default",files=[+# Template files - variable substitutionCyanGlob(root="templates", glob="**/*.md", exclude=[], type=GlobType.TEMPLATE),-CyanGlob(root="template", glob="**/*", exclude=[], type=GlobType.TEMPLATE),+CyanGlob(root="templates", glob="**/*.yaml", exclude=[], type=GlobType.TEMPLATE),CyanGlob(root="templates", glob="**/*.json", exclude=[], type=GlobType.TEMPLATE),CyanGlob(root="templates", glob="**/*.ts", exclude=[], type=GlobType.TEMPLATE),# Binary files - copy only (never process these!)CyanGlob(root="templates", glob="**/*.png", exclude=[], type=GlobType.COPY),CyanGlob(root="templates", glob="**/*.ico", exclude=[], type=GlobType.COPY),# Static directory - copy allCyanGlob(root="static", glob="**/*", exclude=[], type=GlobType.COPY),],config={"vars": {"name": "my-project","author": "Developer"}})])start_template_with_fn(my_template)
Update cyan/Program.cs:
using sulfone_helium;using sulfone_helium.Domain.Core;CyanEngine.StartTemplate(args, async (i, d) =>{return new Cyan{Processors =[new CyanProcessor{Name = "cyan/default",Files =[+// Template files - variable substitutionnew CyanGlob { Root = "templates", Glob = "**/*.md", Exclude = [], Type = GlobType.Template },-new CyanGlob { Root = "template", Glob = "**/*", Exclude = [], Type = GlobType.Template },+new CyanGlob { Root = "templates", Glob = "**/*.yaml", Exclude = [], Type = GlobType.Template },new CyanGlob { Root = "templates", Glob = "**/*.json", Exclude = [], Type = GlobType.Template },new CyanGlob { Root = "templates", Glob = "**/*.ts", Exclude = [], Type = GlobType.Template },// Binary files - copy only (never process these!)new CyanGlob { Root = "templates", Glob = "**/*.png", Exclude = [], Type = GlobType.Copy },new CyanGlob { Root = "templates", Glob = "**/*.ico", Exclude = [], Type = GlobType.Copy },// Static directory - copy allnew CyanGlob { Root = "static", Glob = "**/*", Exclude = [], Type = GlobType.Copy }],Config = new { vars = new { name = "my-project", author = "Developer" } }}]};});
Exclude Patterns
Exclude files from processing:
files: [{root: 'templates',glob: '**/*',exclude: ['**/test/**', // Exclude test directories'**/node_modules/**', // Exclude node_modules'**/*.spec.ts' // Exclude test files],type: GlobType.Template}]
files = [CyanGlob(root="templates",glob="**/*",exclude=["**/test/**", # Exclude test directories"**/node_modules/**", # Exclude node_modules"**/*.spec.ts" # Exclude test files],type=GlobType.TEMPLATE)]
Files =[new CyanGlob{Root = "templates",Glob = "**/*",Exclude =["**/test/**", // Exclude test directories"**/node_modules/**", // Exclude node_modules"**/*.spec.ts" // Exclude test files],Type = GlobType.Template}]
Project Structure Example
Test Your Template
# Builddocker build -f cyan/Dockerfile -t my-first-template:dev .# Testcyanprint create my-first-template:dev ../test-output# Check output - verify images workfile ../test-output/logo.png
For detailed glob syntax, see the Globbing Reference.
What You Learned
- How to use multiple file groups with different processing types
- How to exclude files from processing
- When to use
GlobType.TemplatevsGlobType.CopyvsGlobType.Processor - Why binary files must use
GlobType.Copy
Next Steps
Learn how to ask users for input to customize the generated project: