From 599e8ef7bffeb3eae1eaaaf00dbdadf6d7e01f1b Mon Sep 17 00:00:00 2001 From: Janis Altherr Date: Wed, 1 Dec 2021 15:41:31 +0100 Subject: [PATCH 1/3] Enable the usage of any artifact folder name --- internal/vfs/zip/archive.go | 49 ++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/internal/vfs/zip/archive.go b/internal/vfs/zip/archive.go index 588fb76d1..999cfee0e 100644 --- a/internal/vfs/zip/archive.go +++ b/internal/vfs/zip/archive.go @@ -22,7 +22,6 @@ import ( ) const ( - dirPrefix = "public/" maxSymlinkSize = 256 ) @@ -60,6 +59,8 @@ type zipArchive struct { files map[string]*zip.File directories map[string]*zip.FileHeader + + publicDirectoryName string } func newArchive(fs *zipVFS, openTimeout time.Duration) *zipArchive { @@ -136,9 +137,11 @@ func (a *zipArchive) readArchive(url string) { return } + a.publicDirectoryName = a.guessPublicDirectoryName() + // TODO: Improve preprocessing of zip archives https://gitlab.com/gitlab-org/gitlab-pages/-/issues/432 for _, file := range a.archive.File { - if !strings.HasPrefix(file.Name, dirPrefix) { + if !strings.HasPrefix(file.Name, a.publicDirectoryName) { continue } @@ -177,14 +180,52 @@ func (a *zipArchive) addPathDirectory(pathname string) { } } +func sliceContains(slice []string, value string) bool { + for _, item := range slice { + if item == value { + return true + } + } + return false +} + +func (a *zipArchive) getAllRootDirectories() []string { + rootDirectories := make([]string, 0) + for _, file := range a.archive.File { + fullPath := strings.SplitN(file.Name, "/", 2) + if len(fullPath) < 1 { + break + } + rootDir := fullPath[0] + if !sliceContains(rootDirectories, rootDir) { + rootDirectories = append(rootDirectories, rootDir) + } + } + return rootDirectories +} + +func (a *zipArchive) guessPublicDirectoryName() string { + commonPrefixes := []string{"public", "dist", ".next"} + rootDirectories := a.getAllRootDirectories() + if len(rootDirectories) == 1 { + return rootDirectories[0] + } + for _, pref := range commonPrefixes { + if sliceContains(rootDirectories, pref) { + return pref + } + } + return "" +} + func (a *zipArchive) findFile(name string) *zip.File { - name = path.Clean(dirPrefix + name) + name = path.Clean(a.publicDirectoryName + "/" + name) return a.files[name] } func (a *zipArchive) findDirectory(name string) *zip.FileHeader { - name = path.Clean(dirPrefix + name) + name = path.Clean(a.publicDirectoryName + "/" + name) return a.directories[name+"/"] } -- GitLab From a80fdd4bc37ab2521ac90a741d9254335ec91ac3 Mon Sep 17 00:00:00 2001 From: Janis Altherr Date: Thu, 2 Dec 2021 10:43:24 +0100 Subject: [PATCH 2/3] Update common build output folder names --- internal/vfs/zip/archive.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/vfs/zip/archive.go b/internal/vfs/zip/archive.go index 999cfee0e..8bbfaf8e9 100644 --- a/internal/vfs/zip/archive.go +++ b/internal/vfs/zip/archive.go @@ -205,7 +205,15 @@ func (a *zipArchive) getAllRootDirectories() []string { } func (a *zipArchive) guessPublicDirectoryName() string { - commonPrefixes := []string{"public", "dist", ".next"} + commonPrefixes := []string{ + // A slice of folder names used by popular SSG Frameworks + "public", // previous GitLab behaviour, Hugo, Gatsby, Svelte + // Non-default folder names, ordered by popularity + "build", // React + "dist", // Vue, Nuxt.js, Angular, Astro, Vite + "out", // Next.js + "_site", // Eleventy + } rootDirectories := a.getAllRootDirectories() if len(rootDirectories) == 1 { return rootDirectories[0] -- GitLab From 810fd5987a636c201144d9ff3fd017718d68b48e Mon Sep 17 00:00:00 2001 From: Janis Altherr Date: Thu, 2 Dec 2021 12:02:14 +0100 Subject: [PATCH 3/3] Improve comments and code readability --- internal/vfs/zip/archive.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/internal/vfs/zip/archive.go b/internal/vfs/zip/archive.go index 8bbfaf8e9..b37751edc 100644 --- a/internal/vfs/zip/archive.go +++ b/internal/vfs/zip/archive.go @@ -205,18 +205,23 @@ func (a *zipArchive) getAllRootDirectories() []string { } func (a *zipArchive) guessPublicDirectoryName() string { + rootDirectories := a.getAllRootDirectories() + + // If there's only one directory, use that, no matter what + if len(rootDirectories) == 1 { + return rootDirectories[0] + } + + // If there's multiple directories, perform an educated guess + // as to which is the public folder based on its name commonPrefixes := []string{ - // A slice of folder names used by popular SSG Frameworks + // Folder names used by popular SSG Frameworks "public", // previous GitLab behaviour, Hugo, Gatsby, Svelte // Non-default folder names, ordered by popularity "build", // React "dist", // Vue, Nuxt.js, Angular, Astro, Vite "out", // Next.js - "_site", // Eleventy - } - rootDirectories := a.getAllRootDirectories() - if len(rootDirectories) == 1 { - return rootDirectories[0] + "_site", // Eleventy, Jekyll } for _, pref := range commonPrefixes { if sliceContains(rootDirectories, pref) { -- GitLab