@@ -471,5 +471,126 @@ extension TestCLIBuildBase {
471471 try buildWithStdin ( tags: [ imageName] , tempContext: tempDir, dockerfileContents: dockerfile)
472472 #expect( try self . inspectImage ( imageName) == imageName, " expected to have successfully built \( imageName) " )
473473 }
474+
475+ @Test func testBuildDockerIgnore( ) throws {
476+ let tempDir : URL = try createTempDir ( )
477+ let dockerfile =
478+ """
479+ FROM ghcr.io/linuxcontainers/alpine:3.20
480+
481+ # Copy all files - should respect .dockerignore
482+ COPY . /app
483+
484+ # Verify specific files are excluded
485+ RUN set -e; \
486+ echo " Checking specific file exclusion... " ; \
487+ if [ -f /app/secret.txt ]; then \
488+ echo " ERROR: secret.txt should be excluded! " ; \
489+ exit 1; \
490+ fi
491+
492+ # Verify wildcard *.log files are excluded
493+ RUN set -e; \
494+ echo " Checking *.log exclusion... " ; \
495+ if [ -f /app/debug.log ]; then \
496+ echo " ERROR: debug.log should be excluded by *.log pattern! " ; \
497+ exit 1; \
498+ fi; \
499+ if ls /app/logs/*.log 2>/dev/null; then \
500+ echo " ERROR: logs/*.log files should be excluded! " ; \
501+ exit 1; \
502+ fi
503+
504+ # Verify exception pattern (!important.log) works
505+ RUN set -e; \
506+ echo " Checking exception pattern... " ; \
507+ if [ ! -f /app/important.log ]; then \
508+ echo " ERROR: important.log should be included (exception with !) " ; \
509+ exit 1; \
510+ fi
511+
512+ # Verify *.tmp files are excluded
513+ RUN set -e; \
514+ echo " Checking *.tmp exclusion... " ; \
515+ if find /app -name " *.tmp " | grep .; then \
516+ echo " ERROR: .tmp files should be excluded! " ; \
517+ exit 1; \
518+ fi
519+
520+ # Verify directories are excluded
521+ RUN set -e; \
522+ echo " Checking directory exclusion... " ; \
523+ if [ -d /app/temp ]; then \
524+ echo " ERROR: temp/ directory should be excluded! " ; \
525+ exit 1; \
526+ fi; \
527+ if [ -d /app/node_modules ]; then \
528+ echo " ERROR: node_modules/ should be excluded! " ; \
529+ exit 1; \
530+ fi
531+
532+ # Verify included files ARE present
533+ RUN set -e; \
534+ echo " Checking included files... " ; \
535+ if [ ! -f /app/main.go ]; then \
536+ echo " ERROR: main.go should be included! " ; \
537+ exit 1; \
538+ fi; \
539+ if [ ! -f /app/README.md ]; then \
540+ echo " ERROR: README.md should be included! " ; \
541+ exit 1; \
542+ fi; \
543+ if [ ! -f /app/src/app.go ]; then \
544+ echo " ERROR: src/app.go should be included! " ; \
545+ exit 1; \
546+ fi; \
547+ echo " All .dockerignore checks passed! "
548+ """
549+
550+ let dockerignore =
551+ """
552+ # Exclude specific files
553+ secret.txt
554+
555+ # Exclude all log files
556+ *.log
557+ **/*.log
558+
559+ # But make an exception for important.log
560+ !important.log
561+
562+ # Exclude all temporary files
563+ *.tmp
564+ **/*.tmp
565+
566+ # Exclude directories
567+ temp/
568+ node_modules/
569+ """
570+
571+ let context : [ FileSystemEntry ] = [
572+ . file( " .dockerignore " , content: . data( dockerignore. data ( using: . utf8) !) ) ,
573+ . file( " secret.txt " , content: . data( " secret content " . data ( using: . utf8) !) ) ,
574+ . file( " debug.log " , content: . data( " debug log content " . data ( using: . utf8) !) ) ,
575+ . file( " important.log " , content: . data( " important log content " . data ( using: . utf8) !) ) ,
576+ . file( " cache.tmp " , content: . data( " cache " . data ( using: . utf8) !) ) ,
577+ . file( " main.go " , content: . data( " package main " . data ( using: . utf8) !) ) ,
578+ . file( " README.md " , content: . data( " # README " . data ( using: . utf8) !) ) ,
579+ . directory( " temp " ) ,
580+ . file( " temp/cache.tmp " , content: . data( " temp cache " . data ( using: . utf8) !) ) ,
581+ . directory( " logs " ) ,
582+ . file( " logs/app.log " , content: . data( " app log " . data ( using: . utf8) !) ) ,
583+ . directory( " node_modules " ) ,
584+ . file( " node_modules/package.json " , content: . data( " {} " . data ( using: . utf8) !) ) ,
585+ . directory( " src " ) ,
586+ . file( " src/app.go " , content: . data( " package src " . data ( using: . utf8) !) ) ,
587+ . file( " src/test.tmp " , content: . data( " temp " . data ( using: . utf8) !) ) ,
588+ ]
589+
590+ try createContext ( tempDir: tempDir, dockerfile: dockerfile, context: context)
591+ let imageName = " registry.local/dockerignore-test: \( UUID ( ) . uuidString) "
592+ try self . build ( tag: imageName, tempDir: tempDir)
593+ #expect( try self . inspectImage ( imageName) == imageName, " expected to have successfully built \( imageName) " )
594+ }
474595 }
475596}
0 commit comments