fsx: Remove environment references
This commit removes the reference to the environment from the fsx package.
This commit is contained in:
parent
5a43ecfaeb
commit
3263920d6b
25 changed files with 167 additions and 183 deletions
|
|
@ -72,7 +72,7 @@ var errBootstrapCreateFile = exit.Error{
|
||||||
func (bs cBootstrap) Run(context wisski_distillery.Context) error {
|
func (bs cBootstrap) Run(context wisski_distillery.Context) error {
|
||||||
// installation environment is the native environment!
|
// installation environment is the native environment!
|
||||||
// TODO: Should this be configurable?
|
// TODO: Should this be configurable?
|
||||||
env := new(environment.Native)
|
var env environment.Environment
|
||||||
|
|
||||||
root := bs.Directory
|
root := bs.Directory
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error {
|
||||||
|
|
||||||
{
|
{
|
||||||
logging.LogMessage(context.Stderr, context.Context, "Creating root deployment directory")
|
logging.LogMessage(context.Stderr, context.Context, "Creating root deployment directory")
|
||||||
if err := env.MkdirAll(root, environment.DefaultDirPerm); err != nil {
|
if err := fsx.MkdirAll(root, fsx.DefaultDirPerm); err != nil {
|
||||||
return errBootstrapFailedToCreateDirectory.WithMessageF(root)
|
return errBootstrapFailedToCreateDirectory.WithMessageF(root)
|
||||||
}
|
}
|
||||||
if err := cli.WriteBaseDirectory(env, root); err != nil {
|
if err := cli.WriteBaseDirectory(env, root); err != nil {
|
||||||
|
|
@ -116,7 +116,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error {
|
||||||
return errBoostrapFailedToCopyExe.WithMessageF(err)
|
return errBoostrapFailedToCopyExe.WithMessageF(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fsx.CopyFile(context.Context, env, wdcliPath, exe)
|
err = fsx.CopyFile(context.Context, wdcliPath, exe)
|
||||||
if err != nil && err != fsx.ErrCopySameFile {
|
if err != nil && err != fsx.ErrCopySameFile {
|
||||||
return errBoostrapFailedToCopyExe.WithMessageF(err)
|
return errBoostrapFailedToCopyExe.WithMessageF(err)
|
||||||
}
|
}
|
||||||
|
|
@ -124,15 +124,14 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
if !fsx.IsFile(env, cfgPath) {
|
if !fsx.IsFile(cfgPath) {
|
||||||
// generate the configuration from the template
|
// generate the configuration from the template
|
||||||
cfg := tpl.Generate()
|
cfg := tpl.Generate()
|
||||||
|
|
||||||
// write out all the extra config files
|
// write out all the extra config files
|
||||||
if err := logging.LogOperation(func() error {
|
if err := logging.LogOperation(func() error {
|
||||||
context.Println(cfg.Paths.OverridesJSON)
|
context.Println(cfg.Paths.OverridesJSON)
|
||||||
if err := environment.WriteFile(
|
if err := fsx.WriteFile(
|
||||||
env,
|
|
||||||
cfg.Paths.OverridesJSON,
|
cfg.Paths.OverridesJSON,
|
||||||
bootstrap.DefaultOverridesJSON,
|
bootstrap.DefaultOverridesJSON,
|
||||||
fs.ModePerm,
|
fs.ModePerm,
|
||||||
|
|
@ -141,8 +140,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Println(cfg.Paths.ResolverBlocks)
|
context.Println(cfg.Paths.ResolverBlocks)
|
||||||
if err := environment.WriteFile(
|
if err := fsx.WriteFile(
|
||||||
env,
|
|
||||||
cfg.Paths.ResolverBlocks,
|
cfg.Paths.ResolverBlocks,
|
||||||
bootstrap.DefaultResolverBlockedTXT,
|
bootstrap.DefaultResolverBlockedTXT,
|
||||||
fs.ModePerm,
|
fs.ModePerm,
|
||||||
|
|
@ -162,7 +160,7 @@ func (bs cBootstrap) Run(context wisski_distillery.Context) error {
|
||||||
|
|
||||||
// and marshal it out!
|
// and marshal it out!
|
||||||
if err := logging.LogOperation(func() error {
|
if err := logging.LogOperation(func() error {
|
||||||
configYML, err := env.Create(cfgPath, environment.DefaultFilePerm)
|
configYML, err := fsx.Create(cfgPath, fsx.DefaultFilePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ func (cfgMigrate) Description() wisski_distillery.Description {
|
||||||
|
|
||||||
func (c cfgMigrate) Run(context wisski_distillery.Context) error {
|
func (c cfgMigrate) Run(context wisski_distillery.Context) error {
|
||||||
// migration environment is the native environment!
|
// migration environment is the native environment!
|
||||||
env := new(environment.Native)
|
var env environment.Environment
|
||||||
|
|
||||||
// open the legacy file
|
// open the legacy file
|
||||||
file, err := os.Open(c.Positionals.Input)
|
file, err := os.Open(c.Positionals.Input)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package cmd
|
||||||
import (
|
import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
)
|
)
|
||||||
|
|
@ -29,8 +28,7 @@ func (monday) Description() wisski_distillery.Description {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (monday monday) AfterParse() error {
|
func (monday monday) AfterParse() error {
|
||||||
// TODO: Use a generic environment here!
|
if !fsx.IsFile(monday.Positionals.GraphdbZip) {
|
||||||
if !fsx.IsFile(new(environment.Native), monday.Positionals.GraphdbZip) {
|
|
||||||
return errNoGraphDBZip.WithMessageF(monday.Positionals.GraphdbZip)
|
return errNoGraphDBZip.WithMessageF(monday.Positionals.GraphdbZip)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ func (r reserve) Run(context wisski_distillery.Context) error {
|
||||||
|
|
||||||
// check that the base directory does not exist
|
// check that the base directory does not exist
|
||||||
logging.LogMessage(context.Stderr, context.Context, "Checking that base directory %s does not exist", instance.FilesystemBase)
|
logging.LogMessage(context.Stderr, context.Context, "Checking that base directory %s does not exist", instance.FilesystemBase)
|
||||||
if fsx.IsDirectory(dis.Environment, instance.FilesystemBase) {
|
if fsx.IsDirectory(instance.FilesystemBase) {
|
||||||
return errReserveAlreadyExists.WithMessageF(slug)
|
return errReserveAlreadyExists.WithMessageF(slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
wisski_distillery "github.com/FAU-CDI/wisski-distillery"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/execx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/execx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
|
|
@ -47,7 +46,7 @@ var errNoGraphDBZip = exit.Error{
|
||||||
|
|
||||||
func (s systemupdate) AfterParse() error {
|
func (s systemupdate) AfterParse() error {
|
||||||
// TODO: Use a generic environment here!
|
// TODO: Use a generic environment here!
|
||||||
if !fsx.IsFile(new(environment.Native), s.Positionals.GraphdbZip) {
|
if !fsx.IsFile(s.Positionals.GraphdbZip) {
|
||||||
return errNoGraphDBZip.WithMessageF(s.Positionals.GraphdbZip)
|
return errNoGraphDBZip.WithMessageF(s.Positionals.GraphdbZip)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -76,7 +75,7 @@ func (si systemupdate) Run(context wisski_distillery.Context) error {
|
||||||
dis.Templating().CustomAssetsPath(),
|
dis.Templating().CustomAssetsPath(),
|
||||||
} {
|
} {
|
||||||
context.Println(d)
|
context.Println(d)
|
||||||
if err := dis.Still.Environment.MkdirAll(d, environment.DefaultDirPerm); err != nil {
|
if err := fsx.MkdirAll(d, fsx.DefaultDirPerm); err != nil {
|
||||||
return errBoostrapFailedToCreateDirectory.WithMessageF(d, err)
|
return errBoostrapFailedToCreateDirectory.WithMessageF(d, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ type Parser[T any] func(env environment.Environment, s string) (T, error)
|
||||||
|
|
||||||
// ParseAbspath checks that s is an absolute path and returns it as-is
|
// ParseAbspath checks that s is an absolute path and returns it as-is
|
||||||
func ParseAbspath(env environment.Environment, s string) (string, error) {
|
func ParseAbspath(env environment.Environment, s string) (string, error) {
|
||||||
if !fsx.IsDirectory(env, s) {
|
if !fsx.IsDirectory(s) {
|
||||||
return "", errors.Errorf("%q does not exist or is not a directory", s)
|
return "", errors.Errorf("%q does not exist or is not a directory", s)
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
|
|
@ -32,7 +32,7 @@ func ParseAbspath(env environment.Environment, s string) (string, error) {
|
||||||
|
|
||||||
// ParseFile checks that s is a valid file and returns it as-is
|
// ParseFile checks that s is a valid file and returns it as-is
|
||||||
func ParseFile(env environment.Environment, s string) (string, error) {
|
func ParseFile(env environment.Environment, s string) (string, error) {
|
||||||
if !fsx.IsFile(env, s) {
|
if !fsx.IsFile(s) {
|
||||||
return "", errors.Errorf("%q does not exist or is not a regular file", s)
|
return "", errors.Errorf("%q does not exist or is not a regular file", s)
|
||||||
}
|
}
|
||||||
return s, nil
|
return s, nil
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,14 @@ func (pcfg PathsConfig) UsingDistilleryExecutable(env environment.Environment) b
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return fsx.SameFile(env, exe, pcfg.ExecutablePath())
|
return fsx.SameFile(exe, pcfg.ExecutablePath())
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentExecutable returns the path to the current executable being used.
|
// CurrentExecutable returns the path to the current executable being used.
|
||||||
// When it does not exist, falls back to the default executable.
|
// When it does not exist, falls back to the default executable.
|
||||||
func (pcfg PathsConfig) CurrentExecutable(env environment.Environment) string {
|
func (pcfg PathsConfig) CurrentExecutable(env environment.Environment) string {
|
||||||
exe, err := os.Executable()
|
exe, err := os.Executable()
|
||||||
if err != nil || !fsx.IsFile(env, exe) {
|
if err != nil || !fsx.IsFile(exe) {
|
||||||
return pcfg.ExecutablePath()
|
return pcfg.ExecutablePath()
|
||||||
}
|
}
|
||||||
return exe
|
return exe
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ func ValidateFile(env environment.Environment, path *string, dflt string) error
|
||||||
if *path == "" {
|
if *path == "" {
|
||||||
*path = dflt
|
*path = dflt
|
||||||
}
|
}
|
||||||
if !fsx.IsFile(env, *path) {
|
if !fsx.IsFile(*path) {
|
||||||
return errors.Errorf("%q does not exist or is not a file", *path)
|
return errors.Errorf("%q does not exist or is not a file", *path)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -20,7 +20,7 @@ func ValidateDirectory(env environment.Environment, path *string, dflt string) e
|
||||||
if *path == "" {
|
if *path == "" {
|
||||||
*path = dflt
|
*path = dflt
|
||||||
}
|
}
|
||||||
if !fsx.IsDirectory(env, *path) {
|
if !fsx.IsDirectory(*path) {
|
||||||
return errors.Errorf("%q does not exist or is not a directory", *path)
|
return errors.Errorf("%q does not exist or is not a directory", *path)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ func (sc *stagingContext) CopyFile(dst, src string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sc.sendPath(dst)
|
sc.sendPath(dst)
|
||||||
return fsx.CopyFile(sc.ctx, sc.env, dstPath, src)
|
return fsx.CopyFile(sc.ctx, dstPath, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *stagingContext) CopyDirectory(dst, src string) error {
|
func (sc *stagingContext) CopyDirectory(dst, src string) error {
|
||||||
|
|
@ -160,7 +160,7 @@ func (sc *stagingContext) CopyDirectory(dst, src string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fsx.CopyDirectory(sc.ctx, sc.env, dstPath, src, func(dst, src string) {
|
return fsx.CopyDirectory(sc.ctx, dstPath, src, func(dst, src string) {
|
||||||
sc.sendPath(dst)
|
sc.sendPath(dst)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
"github.com/tkw1536/goprogram/status"
|
"github.com/tkw1536/goprogram/status"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
|
@ -119,7 +119,7 @@ func (backup *Backup) run(ctx context.Context, progress io.Writer, exporter *Exp
|
||||||
defer st.Stop()
|
defer st.Stop()
|
||||||
|
|
||||||
instancesBackupDir := filepath.Join(backup.Description.Dest, "instances")
|
instancesBackupDir := filepath.Join(backup.Description.Dest, "instances")
|
||||||
if err := exporter.Environment.Mkdir(instancesBackupDir, environment.DefaultDirPerm); err != nil {
|
if err := fsx.Mkdir(instancesBackupDir, fsx.DefaultDirPerm); err != nil {
|
||||||
backup.InstanceListErr = err
|
backup.InstanceListErr = err
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -140,7 +140,7 @@ func (backup *Backup) run(ctx context.Context, progress io.Writer, exporter *Exp
|
||||||
|
|
||||||
Handler: func(instance *wisski.WissKI, index int, writer io.Writer) Snapshot {
|
Handler: func(instance *wisski.WissKI, index int, writer io.Writer) Snapshot {
|
||||||
dir := filepath.Join(instancesBackupDir, instance.Slug)
|
dir := filepath.Join(instancesBackupDir, instance.Slug)
|
||||||
if err := exporter.Environment.Mkdir(dir, environment.DefaultDirPerm); err != nil {
|
if err := fsx.Mkdir(dir, fsx.DefaultDirPerm); err != nil {
|
||||||
return Snapshot{
|
return Snapshot{
|
||||||
ErrPanic: err,
|
ErrPanic: err,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/instances"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component/sql"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/passwordx"
|
"github.com/FAU-CDI/wisski-distillery/internal/passwordx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/tkw1536/pkglib/password"
|
"github.com/tkw1536/pkglib/password"
|
||||||
)
|
)
|
||||||
|
|
@ -51,7 +50,7 @@ func (dis *Exporter) ArchivePath() string {
|
||||||
// The path is guaranteed to not exist.
|
// The path is guaranteed to not exist.
|
||||||
func (dis *Exporter) NewArchivePath(prefix string) (path string) {
|
func (dis *Exporter) NewArchivePath(prefix string) (path string) {
|
||||||
// TODO: Consider moving these into a subdirectory with the provided prefix.
|
// TODO: Consider moving these into a subdirectory with the provided prefix.
|
||||||
for path == "" || fsx.Exists(dis.Environment, path) {
|
for path == "" || fsx.Exists(path) {
|
||||||
name := dis.newSnapshotName(prefix) + ".tar.gz"
|
name := dis.newSnapshotName(prefix) + ".tar.gz"
|
||||||
path = filepath.Join(dis.ArchivePath(), name)
|
path = filepath.Join(dis.ArchivePath(), name)
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +74,7 @@ func (*Exporter) newSnapshotName(prefix string) string {
|
||||||
func (dis *Exporter) NewStagingDir(prefix string) (path string, err error) {
|
func (dis *Exporter) NewStagingDir(prefix string) (path string, err error) {
|
||||||
for path == "" || os.IsExist(err) {
|
for path == "" || os.IsExist(err) {
|
||||||
path = filepath.Join(dis.StagingPath(), dis.newSnapshotName(prefix))
|
path = filepath.Join(dis.StagingPath(), dis.newSnapshotName(prefix))
|
||||||
err = dis.Still.Environment.Mkdir(path, environment.DefaultFilePerm)
|
err = fsx.Mkdir(path, fsx.DefaultFilePerm)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
path = ""
|
path = ""
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
"github.com/FAU-CDI/wisski-distillery/internal/models"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
"github.com/FAU-CDI/wisski-distillery/internal/wisski"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/targz"
|
"github.com/FAU-CDI/wisski-distillery/pkg/targz"
|
||||||
"github.com/tkw1536/goprogram/status"
|
"github.com/tkw1536/goprogram/status"
|
||||||
|
|
@ -74,7 +74,7 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta
|
||||||
|
|
||||||
// create the staging directory
|
// create the staging directory
|
||||||
logging.LogMessage(progress, ctx, "Creating staging directory")
|
logging.LogMessage(progress, ctx, "Creating staging directory")
|
||||||
err = exporter.Environment.Mkdir(stagingDir, environment.DefaultDirPerm)
|
err = fsx.Mkdir(stagingDir, fsx.DefaultDirPerm)
|
||||||
if !os.IsExist(err) && err != nil {
|
if !os.IsExist(err) && err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +112,7 @@ func (exporter *Exporter) MakeExport(ctx context.Context, progress io.Writer, ta
|
||||||
logging.ProgressF(progress, ctx, reportPath)
|
logging.ProgressF(progress, ctx, reportPath)
|
||||||
|
|
||||||
// create the path
|
// create the path
|
||||||
report, err := exporter.Environment.Create(reportPath, environment.DefaultFilePerm)
|
report, err := fsx.Create(reportPath, fsx.DefaultFilePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ func (pv *Provision) Provision(progress io.Writer, ctx context.Context, flags Pr
|
||||||
|
|
||||||
// check that the base directory does not exist
|
// check that the base directory does not exist
|
||||||
logging.LogMessage(progress, ctx, "Checking that base directory %s does not exist", instance.FilesystemBase)
|
logging.LogMessage(progress, ctx, "Checking that base directory %s does not exist", instance.FilesystemBase)
|
||||||
if fsx.IsDirectory(pv.Environment, instance.FilesystemBase) {
|
if fsx.IsDirectory(instance.FilesystemBase) {
|
||||||
return nil, ErrInstanceAlreadyExists
|
return nil, ErrInstanceAlreadyExists
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/tkw1536/pkglib/lazy"
|
"github.com/tkw1536/pkglib/lazy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -53,7 +54,7 @@ func (sql *SQL) Stack(env environment.Environment) component.StackWithResources
|
||||||
"HTTPS_ENABLED": sql.Config.HTTP.HTTPSEnabledEnv(),
|
"HTTPS_ENABLED": sql.Config.HTTP.HTTPSEnabledEnv(),
|
||||||
},
|
},
|
||||||
|
|
||||||
MakeDirsPerm: environment.DefaultDirPerm,
|
MakeDirsPerm: fsx.DefaultDirPerm,
|
||||||
MakeDirs: []string{
|
MakeDirs: []string{
|
||||||
"data",
|
"data",
|
||||||
"imports",
|
"imports",
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
"github.com/FAU-CDI/wisski-distillery/pkg/fsx"
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
"github.com/FAU-CDI/wisski-distillery/pkg/logging"
|
||||||
"github.com/gliderlabs/ssh"
|
"github.com/gliderlabs/ssh"
|
||||||
|
|
||||||
|
|
@ -119,7 +119,7 @@ func (ssh2 *SSH2) makeHostKey(progress io.Writer, ctx context.Context, key HostK
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate and write private key as PEM
|
// generate and write private key as PEM
|
||||||
privateKeyFile, err := ssh2.Environment.Create(path, environment.DefaultFilePerm)
|
privateKeyFile, err := fsx.Create(path, fsx.DefaultFilePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -268,7 +268,7 @@ func (is StackWithResources) Install(ctx context.Context, progress io.Writer, co
|
||||||
|
|
||||||
// copy over file from context
|
// copy over file from context
|
||||||
logging.ProgressF(progress, ctx, "[copy] %s (from %s)\n", dst, src)
|
logging.ProgressF(progress, ctx, "[copy] %s (from %s)\n", dst, src)
|
||||||
if err := fsx.CopyFile(ctx, env, dst, src); err != nil {
|
if err := fsx.CopyFile(ctx, dst, src); err != nil {
|
||||||
return errors.Wrapf(err, "Unable to copy file %s", src)
|
return errors.Wrapf(err, "Unable to copy file %s", src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@ import (
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
"github.com/FAU-CDI/wisski-distillery/internal/cli"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
"github.com/FAU-CDI/wisski-distillery/internal/config"
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -23,9 +21,6 @@ var errOpenConfig = exit.Error{
|
||||||
// NewDistillery creates a new distillery from the provided flags
|
// NewDistillery creates a new distillery from the provided flags
|
||||||
func NewDistillery(params cli.Params, flags cli.Flags, req cli.Requirements) (dis *Distillery, err error) {
|
func NewDistillery(params cli.Params, flags cli.Flags, req cli.Requirements) (dis *Distillery, err error) {
|
||||||
dis = &Distillery{
|
dis = &Distillery{
|
||||||
Still: component.Still{
|
|
||||||
Environment: new(environment.Native),
|
|
||||||
},
|
|
||||||
Upstream: Upstream{
|
Upstream: Upstream{
|
||||||
SQL: "127.0.0.1:3306",
|
SQL: "127.0.0.1:3306",
|
||||||
Triplestore: "127.0.0.1:7200",
|
Triplestore: "127.0.0.1:7200",
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ var (
|
||||||
// NoPrefix checks if this WissKI instance is excluded from generating prefixes.
|
// NoPrefix checks if this WissKI instance is excluded from generating prefixes.
|
||||||
// TODO: Move this to the database!
|
// TODO: Move this to the database!
|
||||||
func (prefixes *Prefixes) NoPrefix() bool {
|
func (prefixes *Prefixes) NoPrefix() bool {
|
||||||
return fsx.IsFile(prefixes.Malt.Environment, filepath.Join(prefixes.FilesystemBase, "prefixes.skip"))
|
return fsx.IsFile(filepath.Join(prefixes.FilesystemBase, "prefixes.skip"))
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:embed prefixes.php
|
//go:embed prefixes.php
|
||||||
|
|
@ -120,7 +120,7 @@ func hasAnyPrefix(candidate string, prefixes []string) bool {
|
||||||
|
|
||||||
func (wisski *Prefixes) filePrefixes() (prefixes []string, err error) {
|
func (wisski *Prefixes) filePrefixes() (prefixes []string, err error) {
|
||||||
path := filepath.Join(wisski.FilesystemBase, "prefixes")
|
path := filepath.Join(wisski.FilesystemBase, "prefixes")
|
||||||
if !fsx.IsFile(wisski.Malt.Environment, path) {
|
if !fsx.IsFile(path) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
|
||||||
"github.com/tkw1536/pkglib/contextx"
|
"github.com/tkw1536/pkglib/contextx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -16,16 +15,14 @@ var ErrCopySameFile = errors.New("src and dst must be different")
|
||||||
// CopyFile copies a file from src to dst.
|
// CopyFile copies a file from src to dst.
|
||||||
// When src points to a symbolic link, will copy the symbolic link.
|
// When src points to a symbolic link, will copy the symbolic link.
|
||||||
//
|
//
|
||||||
// When dst and src are the same file, returns ErrCopySameFile.
|
// When dst and src are the same file, returns [ErrCopySameFile].
|
||||||
// When ctx is closed, the file is not copied.
|
// When ctx is closed, the file is not copied.
|
||||||
//
|
func CopyFile(ctx context.Context, dst, src string) error {
|
||||||
// Ignores the umask.
|
|
||||||
func CopyFile(ctx context.Context, env environment.Environment, dst, src string) error {
|
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if SameFile(env, src, dst) {
|
if SameFile(src, dst) {
|
||||||
return ErrCopySameFile
|
return ErrCopySameFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,13 +53,13 @@ func CopyFile(ctx context.Context, env environment.Environment, dst, src string)
|
||||||
|
|
||||||
// CopyLink copies a link from src to dst.
|
// CopyLink copies a link from src to dst.
|
||||||
// If dst already exists, it is deleted and then re-created.
|
// If dst already exists, it is deleted and then re-created.
|
||||||
func CopyLink(ctx context.Context, env environment.Environment, dst, src string) error {
|
func CopyLink(ctx context.Context, dst, src string) error {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// if they're the same file that is an error
|
// if they're the same file that is an error
|
||||||
if SameFile(env, dst, src) {
|
if SameFile(dst, src) {
|
||||||
return ErrCopySameFile
|
return ErrCopySameFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,7 +70,7 @@ func CopyLink(ctx context.Context, env environment.Environment, dst, src string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete it if it already exists
|
// delete it if it already exists
|
||||||
if Exists(env, dst) {
|
if Exists(dst) {
|
||||||
if err := os.Remove(dst); err != nil {
|
if err := os.Remove(dst); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -92,12 +89,12 @@ var ErrDstFile = errors.New("dst is a file")
|
||||||
// When a directory already exists, additional files are not deleted.
|
// When a directory already exists, additional files are not deleted.
|
||||||
//
|
//
|
||||||
// onCopy, when not nil, is called for each file or directory being copied.
|
// onCopy, when not nil, is called for each file or directory being copied.
|
||||||
func CopyDirectory(ctx context.Context, env environment.Environment, dst, src string, onCopy func(dst, src string)) error {
|
func CopyDirectory(ctx context.Context, dst, src string, onCopy func(dst, src string)) error {
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if SameFile(env, src, dst) {
|
if SameFile(src, dst) {
|
||||||
return ErrCopySameFile
|
return ErrCopySameFile
|
||||||
}
|
}
|
||||||
if IsFile(env, dst) {
|
if IsFile(dst) {
|
||||||
return ErrDstFile
|
return ErrDstFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -133,18 +130,18 @@ func CopyDirectory(ctx context.Context, env environment.Environment, dst, src st
|
||||||
|
|
||||||
// if we have a symbolic link, copy the link!
|
// if we have a symbolic link, copy the link!
|
||||||
if info.Mode()&fs.ModeSymlink != 0 {
|
if info.Mode()&fs.ModeSymlink != 0 {
|
||||||
return CopyLink(ctx, env, dst, path)
|
return CopyLink(ctx, dst, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we got a file, we should copy it normally
|
// if we got a file, we should copy it normally
|
||||||
if !d.IsDir() {
|
if !d.IsDir() {
|
||||||
return CopyFile(ctx, env, dst, path)
|
return CopyFile(ctx, dst, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the directory, but ignore an error if the directory already exists.
|
// create the directory, but ignore an error if the directory already exists.
|
||||||
// this is so that we can copy one tree into another tree.
|
// this is so that we can copy one tree into another tree.
|
||||||
err = Mkdir(dst, info.Mode())
|
err = Mkdir(dst, info.Mode())
|
||||||
if os.IsExist(err) && IsDirectory(env, dst) {
|
if os.IsExist(err) && IsDirectory(dst) {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
56
pkg/fsx/create.go
Normal file
56
pkg/fsx/create.go
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
package fsx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Create is like [os.Create] with an additional mode argument.
|
||||||
|
func Create(path string, mode fs.FileMode) (*os.File, error) {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
|
||||||
|
return os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteFile is like [os.WriteFile].
|
||||||
|
func WriteFile(path string, data []byte, mode fs.FileMode) error {
|
||||||
|
handle, err := Create(path, mode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer handle.Close()
|
||||||
|
|
||||||
|
if _, err := handle.Write(data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Touch touches a file.
|
||||||
|
// It is similar to the unix 'touch' command.
|
||||||
|
//
|
||||||
|
// If the file does not exist, it is created using [Create].
|
||||||
|
// If the file does exist, its' access and modification times are updated to the current time.
|
||||||
|
func Touch(path string, perm fs.FileMode) error {
|
||||||
|
if perm == 0 {
|
||||||
|
perm = DefaultFilePerm
|
||||||
|
}
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
switch {
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
f, err := Create(path, perm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
return nil
|
||||||
|
case err != nil:
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
now := time.Now().Local()
|
||||||
|
return os.Chtimes(path, now, now)
|
||||||
|
}
|
||||||
|
}
|
||||||
25
pkg/fsx/dir.go
Normal file
25
pkg/fsx/dir.go
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
package fsx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DefaultDirPerm should be used by callers to use a consistent mode for new directories.
|
||||||
|
const DefaultDirPerm fs.FileMode = fs.ModeDir | fs.ModePerm
|
||||||
|
|
||||||
|
// Mkdir is like [os.Mkdir].
|
||||||
|
func Mkdir(path string, mode fs.FileMode) error {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
|
||||||
|
return os.Mkdir(path, fs.ModeDir|mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MkdirAll is like [os.MkdirAll].
|
||||||
|
func MkdirAll(path string, mode fs.FileMode) error {
|
||||||
|
m.Lock()
|
||||||
|
defer m.Unlock()
|
||||||
|
|
||||||
|
return os.MkdirAll(path, fs.ModeDir|mode)
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,37 @@
|
||||||
// Package fsx provides additional file system functionality.
|
// Package fsx provides additional file system functionality.
|
||||||
//
|
//
|
||||||
// Several functions in this package provide umask-ignoring functions.
|
// All functions in this package ignore the umask.
|
||||||
// Using these functions intervenes with the global umask.
|
// As such it is not safe to use otherwise equivalent functions provided by the standard go library concurrently with this package.
|
||||||
//
|
|
||||||
// It is not safe to use functions provided by the standard go library concurrently with this function.
|
|
||||||
// Users should take care that no other code in their application uses these functions.
|
// Users should take care that no other code in their application uses these functions.
|
||||||
package fsx
|
package fsx
|
||||||
|
|
||||||
import "io/fs"
|
import (
|
||||||
|
"io/fs"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
// DefaultFilePerm should be used by callers to use a consistent file mode for new files.
|
// DefaultFilePerm should be used by callers to use a consistent file mode for new files.
|
||||||
const DefaultFilePerm fs.FileMode = 0666
|
const DefaultFilePerm fs.FileMode = 0666
|
||||||
|
|
||||||
// DefaultDirPerm should be used by callers to use a consistent mode for new directories.
|
// mask is the global mask lock
|
||||||
const DefaultDirPerm fs.FileMode = fs.ModeDir | fs.ModePerm
|
var m mask
|
||||||
|
|
||||||
|
// mask allows disabling and re-enabling the global umask.
|
||||||
|
// it is used by allow functions of this package.
|
||||||
|
type mask struct {
|
||||||
|
l sync.Mutex // locked?
|
||||||
|
umask int // previous mask
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lock blocks until no other function is using this umask
|
||||||
|
// and then sets it to 0.
|
||||||
|
func (mask *mask) Lock() {
|
||||||
|
mask.l.Lock()
|
||||||
|
mask.umask = syscall.Umask(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mask *mask) Unlock() {
|
||||||
|
mask.umask = syscall.Umask(mask.umask)
|
||||||
|
mask.l.Unlock()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,15 @@ package fsx
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SameFile checks if path1 and path2 refer to the same file.
|
// SameFile checks if path1 and path2 refer to the same file.
|
||||||
// If both files exist, they are compared using [env.SameFile].
|
// If both files exist, they are compared using [os.SameFile].
|
||||||
// If both files do not exist, the paths are first compared syntactically and then via recursion on [filepath.Dir].
|
// If both files do not exist, the paths are first compared syntactically and then via recursion on [filepath.Dir].
|
||||||
func SameFile(env environment.Environment, path1, path2 string) bool {
|
func SameFile(path1, path2 string) bool {
|
||||||
|
|
||||||
// initial attempt: check if directly
|
// initial attempt: check if directly
|
||||||
same, certain := couldBeSameFile(env, path1, path2)
|
same, certain := couldBeSameFile(path1, path2)
|
||||||
if certain {
|
if certain {
|
||||||
return same
|
return same
|
||||||
}
|
}
|
||||||
|
|
@ -30,19 +28,19 @@ func SameFile(env environment.Environment, path1, path2 string) bool {
|
||||||
|
|
||||||
// compare the base names!
|
// compare the base names!
|
||||||
{
|
{
|
||||||
same, _ := couldBeSameFile(env, d1, d2)
|
same, _ := couldBeSameFile(d1, d2)
|
||||||
return same
|
return same
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// couldBeSameFile checks if path1 might be the same as path2.
|
// couldBeSameFile checks if path1 might be the same as path2.
|
||||||
//
|
//
|
||||||
// If both files exist, compares using [env.SameFile].
|
// If both files exist, compares using [os.SameFile].
|
||||||
// Otherwise compares absolute paths using string comparison.
|
// Otherwise compares absolute paths using string comparison.
|
||||||
//
|
//
|
||||||
// same indicates if they might be the same file.
|
// same indicates if they might be the same file.
|
||||||
// authorative indiciates if the result is authorative.
|
// authorative indiciates if the result is authorative.
|
||||||
func couldBeSameFile(env environment.Environment, path1, path2 string) (same, authorative bool) {
|
func couldBeSameFile(path1, path2 string) (same, authorative bool) {
|
||||||
{
|
{
|
||||||
// stat both files
|
// stat both files
|
||||||
info1, err1 := os.Stat(path1)
|
info1, err1 := os.Stat(path1)
|
||||||
|
|
|
||||||
|
|
@ -4,30 +4,28 @@ package fsx
|
||||||
import (
|
import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/pkg/environment"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Exists checks if the given path exists
|
// Exists checks if the given path exists
|
||||||
func Exists(env environment.Environment, path string) bool {
|
func Exists(path string) bool {
|
||||||
_, err := os.Lstat(path)
|
_, err := os.Lstat(path)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDirectory checks if the provided path exists and is a directory
|
// IsDirectory checks if the provided path exists and is a directory
|
||||||
func IsDirectory(env environment.Environment, path string) bool {
|
func IsDirectory(path string) bool {
|
||||||
info, err := os.Stat(path)
|
info, err := os.Stat(path)
|
||||||
return err == nil && info.Mode().IsDir()
|
return err == nil && info.Mode().IsDir()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsFile checks if the provided path exists and is a regular file
|
// IsFile checks if the provided path exists and is a regular file
|
||||||
func IsFile(env environment.Environment, path string) bool {
|
func IsFile(path string) bool {
|
||||||
info, err := os.Stat(path)
|
info, err := os.Stat(path)
|
||||||
return err == nil && info.Mode().IsRegular()
|
return err == nil && info.Mode().IsRegular()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLink checks if the provided path exists and is a symlink
|
// IsLink checks if the provided path exists and is a symlink
|
||||||
func IsLink(env environment.Environment, path string) bool {
|
func IsLink(path string) bool {
|
||||||
info, err := os.Lstat(path)
|
info, err := os.Lstat(path)
|
||||||
return err == nil && info.Mode()&fs.ModeSymlink != 0
|
return err == nil && info.Mode()&fs.ModeSymlink != 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
package fsx
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/fs"
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// mask is the global mask lock
|
|
||||||
var m mask
|
|
||||||
|
|
||||||
// mask allows disabling and re-enabling the global umask.
|
|
||||||
// it is used by allow functions of this package.
|
|
||||||
type mask struct {
|
|
||||||
l sync.Mutex // locked?
|
|
||||||
umask int // previous mask
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lock blocks until no other function is using this umask
|
|
||||||
// and then sets it to 0.
|
|
||||||
func (mask *mask) Lock() {
|
|
||||||
mask.l.Lock()
|
|
||||||
mask.umask = syscall.Umask(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mask *mask) Unlock() {
|
|
||||||
mask.umask = syscall.Umask(mask.umask)
|
|
||||||
mask.l.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteFile is like [os.WriteFile], but ignores the umask.
|
|
||||||
func WriteFile(path string, data []byte, mode fs.FileMode) error {
|
|
||||||
handle, err := Create(path, mode)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer handle.Close()
|
|
||||||
|
|
||||||
if _, err := handle.Write(data); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create creates a new file with the given mode.
|
|
||||||
// This function ignores the umask.
|
|
||||||
func Create(path string, mode fs.FileMode) (*os.File, error) {
|
|
||||||
m.Lock()
|
|
||||||
defer m.Unlock()
|
|
||||||
|
|
||||||
return os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mkdir creates a new directory with the given mode.
|
|
||||||
// This function ignores the umask.
|
|
||||||
func Mkdir(path string, mode fs.FileMode) error {
|
|
||||||
m.Lock()
|
|
||||||
defer m.Unlock()
|
|
||||||
|
|
||||||
return os.Mkdir(path, fs.ModeDir|mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MkdirAll creates a new directory and all potentially missing parent directories.
|
|
||||||
// This function ignores the umask.
|
|
||||||
func MkdirAll(path string, mode fs.FileMode) error {
|
|
||||||
m.Lock()
|
|
||||||
defer m.Unlock()
|
|
||||||
|
|
||||||
return os.MkdirAll(path, fs.ModeDir|mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Touch touches a file.
|
|
||||||
// It is similar to the unix 'touch' command.
|
|
||||||
//
|
|
||||||
// If the file does not exist exists, it is created using [Create].
|
|
||||||
// If the file does exist, it's access and modification times are updated to the current time.
|
|
||||||
//
|
|
||||||
// This function ignores the umask.
|
|
||||||
func Touch(path string, perm fs.FileMode) error {
|
|
||||||
if perm == 0 {
|
|
||||||
perm = DefaultFilePerm
|
|
||||||
}
|
|
||||||
_, err := os.Stat(path)
|
|
||||||
switch {
|
|
||||||
case os.IsNotExist(err):
|
|
||||||
f, err := Create(path, perm)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
return nil
|
|
||||||
case err != nil:
|
|
||||||
return err
|
|
||||||
default:
|
|
||||||
now := time.Now().Local()
|
|
||||||
return os.Chtimes(path, now, now)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue