Tuesday, September 25, 2018

First Open Source Experience

The First Step

Diving into a open source project was intimidating and frustrating, I spent a few hours just trying to get comfortable with the project space. Then I figured I would delve deep into the source code and try to understand how it all came together. This was... a mistake, not because the code is horribly written or anything it's just that I didn't have the time to learn this whole API. It was like trying to put a big puzzle together, It could be done but I had nowhere near the time or patience to do it. So I settled on porting a stat test to use the new Promise API in fs. This is what I think I should have done in the first place, don't dive straight in maybe just wet my feet and see how it feels. I opened up an issue and away I went.

The Nitty Gritty

The test I chose to port was this one. I had some knowledge of stat from the previous post so I could understand almost all of what was going on in here. First of all I made a branch that was call issue-423 (423 being the number on my issue). It was pretty easy to convert to using promises, just import the library, switch the callback to .then/.catch and that was it, I pushed it to my branch and made my pull request and thought I was finished. Except I had a few bugs that I wasn't aware of. Thankfully open-source community was there to help and they pointed out all the things I could improve. For instance changing my test be more promise-friendly and some style fixes, things that I wouldn't have thought of like returning the whole promise since the it() function can handle them. GitHub also made this process really fluid since all changes that I made in my local branch were reflected in the pull request. Even though I made the initial code I felt everyone who posted reviews helped write it.

The Give Back

After getting good feedback and improving my pull request I thought it was about time I re-payed the favor. I basically took what others suggested about my code and applied it to other pull requests. Like here and here. Overall I feel like not only my code got better but I helped other people learn as well. Working in open-source made me fix things that normally I would be too lazy to, it also helped motivate me learn git which I struggled with for quite some time.

Thursday, September 13, 2018

NodeJS Stat

The Basics

If you're not familiar with stat I will give you a quick rundown. Stat is used in UNIX to view information about a file. In the fs module of NodeJs most stat related functions return a Stats object. This is what is looks like in the documentation.
Stats {
  dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  atimeMs: 1318289051000.1,
  mtimeMs: 1318289051000.1,
  ctimeMs: 1318289051000.1,
  birthtimeMs: 1318289051000.1,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT,
  birthtime: Mon, 10 Oct 2011 23:24:11 GMT } 

This object holds a lot of information that seems to be irrelevant to us, but in reality it is all useful! I made a handy reference sheet so that the file statistics represent
 
  dev: Device ID
  ino: Inode number
  mode: File type and mode
  nlink: Number of links
  uid: User ID of owner
  gid: Group ID of owner
  rdev: Device ID (if special file)
  size: Total size in bytes
  blksize: Block size of file system I/O
  blocks: Number of 512 byte blocks allocated
  atimeMs: Time of last access in milliseconds
  mtimeMs: Time of last modification in milliseconds
  ctimeMs: Time of last status change in milliseconds
  birthtimeMs: Time of creation in milliseconds
  atime: Time of last access 
  mtime: Time of last modification
  ctime: Time of last status
  birthtime: Time of creation 

Lets put our new knowledge to use.
const fs = require("fs");
let filepath = "test1.txt";
fs.stat(filepath, (err, stats) => {
    if (err) {
        console.log(err);
    } else {
        console.log("Date Created: ");
        console.log(stats.birthtime);
        console.log("Date Accessed: ");
        console.log(stats.atime);
        console.log("Date Modified: ");
        console.log(stats.mtime);
        console.log("Date Changed: ");
        console.log(stats.ctime);
    }
});

Output:

Date Created: 
2018-09-13T22:04:58.180Z
Date Accessed: 
2018-09-13T22:04:58.180Z
Date Modified: 
2018-09-13T22:04:58.180Z
Date Changed: 
2018-09-13T22:04:58.180Z

We can also do the same thing using fsPromises
const fsPromises = require("fs").promises;
let filepath = "test1.txt";
let statPromise = fsPromises.stat(filepath);
statPromise.then((stats) => {
        console.log("Date Created: ");
        console.log(stats.birthtime);
        console.log("Date Accessed: ");
        console.log(stats.atime);
        console.log("Date Modified: ");
        console.log(stats.mtime);
        console.log("Date Changed: ");
        console.log(stats.ctime);
    }).catch((err) => {
        console.log(err); 
});

lstat works similarly to stat except if the filepath is a symbolic link the link in statted instead of the file. fstat takes a file descriptor instead of a filepath. To use fstat open a file using fs then using the file descrpitor from the opfunction and pass it into fstat
It would look something like this:
const fs = require("fs");
let filepath = "test1.txt";
fs.open(filepath, 'r', (err, fd) =>{
      if (err) console.log(err);
      console.log(fd);
      fs.fstat(fd, (err, stats) => {
          if (err) {
              console.log(err);
          } else {
              console.log(stats);
          }
      });
      // always close the file descriptor!
      fs.close(fd, (err) => {
          if (err) throw err;
      });
 });


Creating Releases