DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Join us tomorrow at 1 PM EST: "3-Step Approach to Comprehensive Runtime Application Security"
Save your seat

A Go Repo and Some Go Code [Video]

In this code along video, a developer demonstrates how to program in Go, using an open source app he's created as a means of example.

Adron Hall user avatar by
Adron Hall
CORE ·
Oct. 11, 18 · Tutorial
Like (2)
Save
Tweet
Share
5.78K Views

Join the DZone community and get the full member experience.

Join For Free

Wrapped up another Twitch stream (follow here) and streamed live via YouTube where the video is now (subscribe here, video here). However, the more interesting part, in my opinion, was where I broke down a few key parts of the application building features around file writes, reads, JSON marshaling, and some other functionality. I also put together a repo of the code I used here on Github (code shown and explained below). I dove into this topic in the later part of the stream which I've time tagged below. For the full timeline and the rest of the video just watch from the beginning. I do make some progress working on Colligere, but I'll cover that topic in a subsequent blog entry and Twitch stream.


  • 1:32:40 - Creating a new application with Jetbrains Goland to show off how to use the Go core libraries around the user, JSON, and some basic file creation and writing.
  • 1:36:40 - At this point, I start adding some basic code to pull the current user and collect some information about that user.
  • 1:40:42 - I extract the error code using the Goland refactoring feature and set up a func check() for error checking. That cleans up the inline code a bit.
  • 1:43:10 - Here I add to the user data retrieved some environment variables to that list of collected data. I also cover again, as I have a number of times, how the environment variables are pulled in IDE versus user session versus out of IDE.
  • 1:47:46 - Now I add a file exist, check, and start working on that logic.
  • 1:48:56 - Props to Edd Turtle on a solid site on Go. Here's the blog entry, and respectively the path to more of Edd's material @ https://golangcode.com/. Also, Edd seems like a good guy to follow @eddturtle.
  • 2:01:33 - Starting the JSON Work here to marshal and unmarshall.
  • 2:26:33 - At this point, I push the code up to GitHub (repo here) using the built-in Goland VCS features. I realize I've named the repo "adron" by accident so I rename it, close Goland, and then clone the code back down locally with Goland's VCS features. It's kind of interesting to see Goland go through the two-factor auth for this too.
  • 2:58:56 - The Seattle Thrashing Code outtro!

There were a few notes I took during the session with my collected links and references for things I looked up. Those included the following:

  • File Modes for Go folder creation: https://golang.org/pkg/os/#FileMode
  • My ref letter and number. File permissions: https://www-s.acm.illinois.edu/webmonkeys/html_workshop/unix.html
  • Excellent little permissions map written in ASCII/. Yay! https://stackoverflow.com/questions/14249467/os-mkdir-and-os-mkdirall-permission-value

The code for the Github repo ended in this state. Just a single main.go file, which shows how to use several features of Go and capabilities of the core libraries.

package main

import (
    "encoding/json"
    "io/ioutil"
    "log"
    "os"
    "os/user"
    "strconv"
)

type UserInformation struct {
    Name     string   `json:"name"`
    UserId   int64    `json:"userid"`
    GroupId  int64    `json:"groupid"`
    HomeDir  string   `json:"homedir"`
    UserName string   `json:"username"`
    GroupIds []string `json:"groupids"`
    GoPath   string   `json:"gopath"`
    EnvVar   string   `json:"environmentvariable"`
}

func main() {
    currentUser, err := user.Current()
    check(err)
    changeDataForMarshalling(currentUser)
}

func changeDataForMarshalling(currentUser *user.User) {
    groupsIds, err := currentUser.GroupIds()
    check(err)
    userId, err := strconv.ParseInt(currentUser.Uid, 6, 64)
    check(err)
    groupId, err := strconv.ParseInt(currentUser.Gid, 6, 64)
    check(err)

    workingUserInformation := &UserInformation{
        Name:     currentUser.Name,
        UserId:   userId,
        GroupId:  groupId,
        HomeDir:  currentUser.HomeDir,
        UserName: currentUser.Username,
        GroupIds: groupsIds,
        GoPath:   os.Getenv("GOPATH"),
        EnvVar:   os.Getenv("NEW_STRING_ENVIRONMENT_VARIABLE"),
    }

    resultingUserInformation, _ := json.Marshal(workingUserInformation)

    filename := "collected_values.json"
    if _, err := os.Stat(filename); os.IsNotExist(err) {
        writeFileContents(err, filename, string(resultingUserInformation))
    } else {
        newUserInformation, err := openFileMakeChanges(filename)
        writeFileContents(err, filename, newUserInformation)
    }
}

func openFileMakeChanges(filename string) (string, error) {
    jsonFile, err := os.Open(filename)
    check(err)
    defer jsonFile.Close()
var changingUserInformation UserInformation
    byteValue, _ := ioutil.ReadAll(jsonFile)
    json.Unmarshal(byteValue, &changingUserInformation)
changingUserInformation.Name = "Adron Hall"
    changingUserInformation.GoPath = "/where/is/the/goland"
    newUserInformation, _ := json.Marshal(changingUserInformation)
return string(newUserInformation), err
}

func writeFileContents(err error, filename string, text string) {
    f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0600)
    check(err)
    defer f.Close()

    if _, err = f.WriteString(text); err != nil {
        panic(err)
    }
}

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

The import section includes several core libraries for the application "encoding/json", "io/ioutil", "log", "os", "os/user", and "strconv". Then I've got a structure declared that I use throughout the code with various fields.

Then, just for the heck of it, I created a changeDataForMarshalling function and passed in userInfo and parsed the string results of gid and uid to int data types. From there, the remaining values are passed in then marshaled to JSON and written to a file, depending on if it's a new file or existing. The writing, however, I broke out to a function dubbed writeFileContents. Definitely some more refactoring and tweaking to really make it functional and usable, but shows easily what strconv, marshaling, and other features of these core libraries do. This code provides some examples on what functionality Colligere will use to read in schema configuration, edit, and save that schema. More about that in the next Twitch few streams.

Published at DZone with permission of Adron Hall, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How Do the Docker Client and Docker Servers Work?
  • PostgreSQL: Bulk Loading Data With Node.js and Sequelize
  • Visual Network Mapping Your K8s Clusters To Assess Performance
  • Why Does DevOps Recommend Shift-Left Testing Principles?

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: