func (f *FileSystem) Open(ctx context.Context, root, pwd string, eg *errgroup.Group) error {
	fsys, err := f.compressor.OpenWithPwd(root, pwd)
	if err != nil {
		return err
	}
	f.archivers = []*file{}
	f.rootName = filepath.Base(root)
	err = fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.IsDir() {
			switch path {
			case ".git":
				return fs.SkipDir
			case compress.DefaultArchiverRoot:
				return nil
			default:
				return nil
				// --- Directory doesn't make sense when std_zip is compressed?
				// --- Only need root to set the right zip will create the directory itself?
				//var info fs.FileInfo
				//info, err = d.Info()
				//if err != nil {
				//	return err
				//}
				//if info.Name() == f.rootName {
				//	return nil
				//}
				//f.archivers = append(f.archivers, file{
				//	FileInfo: info,
				//	root:     path,
				//})
			}
		} else {
			// Image file filter
			for _, ext := range f.Extensions {
				fileExt := filepath.Ext(strings.ToLower(path))
				if ext == fileExt {
					var info fs.FileInfo
					info, err = d.Info()
					if err != nil {
						return err
					}
					buf := &mem.FakeIO{}
					buf.Grow(int(info.Size()))
					image := &images.ImageData{FakeIO: buf}
					f.archivers = append(f.archivers, &file{
						FileInfo: info,
						ext:      fileExt,
						root:     path,
						read:     image.Read,
						write:    image.Write,
						close:    image.Close,
					})
					f.Cache.NewImage(image, path)
				}
			}
		}
		return nil
	})

	// Read the file and write to the cache system
	f.Cache.WaitGroupAdd(1)
	eg.Go(func() error {
		defer func() {
			f.Cache.WaitGroupDone()
			f.Cache.CloseSend()
			_ = f.compressor.Close()
		}()
		for _, file := range f.archivers {
			select {
			case <-ctx.Done():
				err := ctx.Err()
				if errors.Is(err, context.Canceled) {
					log.Debug("file system is canceled")
					return nil
				}
				return err
			default:
				if file.IsDir() {
					continue
				}
				af, err := fsys.Open(file.root)
				if err != nil {
					return err
				}
				image := f.Cache.GetImageBuffer(file.root)
				n, err := io.Copy(image, af)
				_ = af.Close()
				if err != nil {
					return err
				}
				if n != image.Size() {
					return ErrArchiverReadSize
				}
				f.Cache.Send() <- file.root
			}
		}
		return nil
	})

	return err
}
// Open is set archiver path or local directory path
Open is set archiver path or local directory path
// Open is set archiver path or local directory path
func (f *FileSystem) Open(ctx context.Context, root, pwd string, eg *errgroup.Group) error {
	fsys, err := f.compressor.OpenWithPwd(root, pwd)
	if err != nil {
		return err
	}
	f.archivers = []*file{}
	f.rootName = filepath.Base(root)
	err = fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.IsDir() {
			switch path {
			case ".git":
				return fs.SkipDir
			case compress.DefaultArchiverRoot:
				return nil
			default:
				return nil
				)
			}
		} else {
			for _, ext := range f.Extensions {
				fileExt := filepath.Ext(strings.ToLower(path))
				if ext == fileExt {
					var info fs.FileInfo
					info, err = d.Info()
					if err != nil {
						return err
					}
					buf := &mem.FakeIO{}
					buf.Grow(int(info.Size()))
					image := &images.ImageData{FakeIO: buf}
					f.archivers = append(f.archivers, &file{
						FileInfo: info,
						ext:      fileExt,
						root:     path,
						read:     image.Read,
						write:    image.Write,
						close:    image.Close,
					})
					f.Cache.NewImage(image, path)
				}
			}
		}
		return nil
	})
	f.Cache.WaitGroupAdd(1)
	eg.Go(func() error {
		defer func() {
			f.Cache.WaitGroupDone()
			f.Cache.CloseSend()
			_ = f.compressor.Close()
		}()
		for _, file := range f.archivers {
			select {
			case <-ctx.Done():
				err := ctx.Err()
				if errors.Is(err, context.Canceled) {
					log.Debug("file system is canceled")
					return nil
				}
				return err
			default:
				if file.IsDir() {
					continue
				}
				af, err := fsys.Open(file.root)
				if err != nil {
					return err
				}
				image := f.Cache.GetImageBuffer(file.root)
				n, err := io.Copy(image, af)
				_ = af.Close()
				if err != nil {
					return err
				}
				if n != image.Size() {
					return ErrArchiverReadSize
				}
				f.Cache.Send() <- file.root
			}
		}
		return nil
	})
	return err
}
func ( f * FileSystem ) Open ( ctx context . Context , root , pwd string , eg * errgroup . Group ) error { fsys , err := f . compressor . OpenWithPwd ( root , pwd ) if err != nil { return err } f . archivers = [ ] * file { } f . rootName = filepath . Base ( root ) err = fs . WalkDir ( fsys , " " , func ( path string , d fs . DirEntry , err error ) error { if err != nil { return err } if d . IsDir ( ) { switch path { case " " : return fs . SkipDir case compress . DefaultArchiverRoot : return nil default : return nil } } else { for _ , ext := range f . Extensions { fileExt := filepath . Ext ( strings . ToLower ( path ) ) if ext == fileExt { var info fs . FileInfo info , err = d . Info ( ) if err != nil { return err } buf := & mem . FakeIO { } buf . Grow ( int ( info . Size ( ) ) ) image := & images . ImageData { FakeIO : buf } f . archivers = append ( f . archivers , & file { FileInfo : info , ext : fileExt , root : path , read : image . Read , write : image . Write , close : image . Close , } ) f . Cache . NewImage ( image , path ) } } } return nil } ) f . Cache . WaitGroupAdd ( 1 ) eg . Go ( func ( ) error { defer func ( ) { f . Cache . WaitGroupDone ( ) f . Cache . CloseSend ( ) _ = f . compressor . Close ( ) } ( ) for _ , file := range f . archivers { select { case <- ctx . Done ( ) : err := ctx . Err ( ) if errors . Is ( err , context . Canceled ) { log . Debug ( " " ) return nil } return err default : if file . IsDir ( ) { continue } af , err := fsys . Open ( file . root ) if err != nil { return err } image := f . Cache . GetImageBuffer ( file . root ) n , err := io . Copy ( image , af ) _ = af . Close ( ) if err != nil { return err } if n != image . Size ( ) { return ErrArchiverReadSize } f . Cache . Send ( ) <- file . root } } return nil } ) return err }
Open is set archiver path or local directory path
Open is set archiver path or local directory path
// --- Directory doesn't make sense when std_zip is compressed? // --- Only need root to set the right zip will create the directory itself? //var info fs.FileInfo //info, err = d.Info() //if err != nil { //	return err //} //if info.Name() == f.rootName { //	return nil //} //f.archivers = append(f.archivers, file{ //	FileInfo: info, //	root:     path, //}) // Image file filter // Read the file and write to the cache system