goFAL - File Abstraction in Go
When writing scripts that create or manipulate file and directories, it’s all too easy to get lost using chmod
and chdir
operating system directives. Move here, do that, change this, write that. Bah. Unless you track very carefully what directory your script is working in, it’s all too easy to get lost. There is always an easier way.
After a quick hunt around using my Google powers and checking out various Go sites, I didn’t find what I was looking for. That might have been due to not looking for the right thing or using the correct keywords, but find it I did not. Therefore, the next logical step was to build what I required, then consume. The result may prove useful.
How do we use it?
- Build a root node
- Add directories or files using the concept of parents
- Generate the tree
- Manipulate the file contents
- Generate hashes
- Set permissions
- Use
Steps 1 through 6 rely on exported package level functions with package level constants for ease of use.
What does goFAL stand for? goFAL = Go File Abstraction Layer
.
Example
The example makes use of Godeps, so restore the dependencies with ease and build.
cd exampleCode
godep restore
go build
./exampleCode
This assumes a working Go toolchain install. I always work with the latest stable. Simples.
This example involves:
- Create root directory
- Create content directory
- Create file in root directory
- Create file in content directory
Each file and directory has permissions associated with them. Hashes will only be calculated for files.
Source code is here.
/*
Copyright 2018 David Gee
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"os"
"github.com/Sirupsen/logrus"
gf "github.com/arsonistgopher/gofal"
)
func main() {
/*
Example of how to use the goFAL package.
goFAL builds a tree of file type instances. This tree is then used
to build a real file tree when the correct package functions are called.
Each file has both SHA1 and SHA256 hashes calculated for easy use.
This was created to make projects easier to build for packaging and scripting.
This is an alpha release at best and comes without support.
Author: David Gee
Copyright: David Gee
Date: 20th April 2018
Contributors welcome!
*/
logrus.Info("--- Welcome to the goFAL Demo ---")
// Create root node called 'build'
build, err := gf.BuildRoot("build", os.ModePerm)
if err != nil {
logrus.Error(err)
}
// Add a content directory called 'content' and set the permissions
content, err := gf.BuildNode(build, "content", os.ModePerm, gf.DIR)
if err != nil {
logrus.Error(err)
}
// Add a file under the build directory called 'content1' and set perms
file1, err := gf.BuildNode(build, "content1.txt", 0444, gf.FILE)
if err != nil {
logrus.Error(err)
}
// Add a file under the content directory called 'content2' and set perms
file2, err := gf.BuildNode(content, "content2.txt", 0444, gf.FILE)
if err != nil {
logrus.Error(err)
}
// Generate file tree on disk
err = gf.Generate(build)
if err != nil {
logrus.Error(err)
}
// Insert content
file1Content := []byte("Hello from ArsonistGopher once.")
file2Content := []byte("Hello from ArsonistGopher twice.")
err = gf.FileWrite(file1, file1Content)
if err != nil {
logrus.Error(err)
}
err = gf.FileWrite(file2, file2Content)
if err != nil {
logrus.Error(err)
}
// Create hashes using the build root as an anchor
err = gf.BuildHashes(build)
if err != nil {
logrus.Error(err)
}
// Set permissions (post writing) as per tree data
err = gf.SetPerms(build)
if err != nil {
logrus.Error(err)
}
// Uncomment line below to print build info
// fmt.Println(build.String())
// Because we have a String() method, we can also call print directly. Uncomment line below.
// fmt.Print(build)
// This builds our stringfied object tree
fmt.Println(build.TreeString())
}
Note, it’s possible to print out string representations of the tree nodes in a couple of ways which includes the full tree with hierarchical indentations. Two examples below. TreeString will print the tree from the perspective of the node that TreeString()
is being called on.
fmt.Println(<node>)
fmt.Println(<node>.TreeString())
Tree output as follows:
Dir/File Perm(Octal)
build 0755
├── content 0777
│ └── content2.txt 0444
└── content1.txt 0444
ToDo
- Write some tests
- Add signature capabilities for specific branches or the tree
The Burn Down
This made my life easier!
Contributing
Fork and work on master. Create PR and I’ll review.
// Dave
- Tags: Golang
- Categories: Golang