Tuesday, September 25, 2018

My First Pull Request to an Open Source Project

I've worked with GitHub before for private projects but have always wanted to contribute to an Open Source project. The problem was that I didn't know how to start. All these projects that I have looked at seemed way too complicated - I didn't want to spend hours learning the codebase. My problem wasn't not knowing the where to start, it was not knowing how to start. Thanks to my Open Source elective in school, I learned what to look for to get started in a larger project. I shouldn't be trying to learn the entire codebase - that would take way too long - instead, I should learn how to read smaller chunks of code in a way efficient for an issue that I would want to tackle.


What I Worked On

I contributed to an Open Source Node.js project called filer. This was a great first project to work on because of how much I learned. I wrote a [f]chmod test for Node.js's Promises module. Note that I have not coded in Node.js before, so I was a bit intimidated coming into this project. But having access to other tests helped me a lot - I didn't have to actually learn the language at a professional level to be able to contribute - I was able to see what the other tests did and mimic that style, applying it to my objective.


Trial and .catch( error )

After I studied the other test function, I began on working on the chmod and fchmod Promise tests. I quickly ran into a problem. Having to create a file, change its mode with chmod and fchmod, and then check if the mode was actually changed with stat and fstat required me to nest my function - doesn't sound too difficult but since I never used Promises. When purposly changing some values to see what it would do if it would ever fail, I found out that the way that I wrote my function did not call the done() function which signalled the end of the test. Something weird was happening, it would catch the error (I think?) but wouldn't print the error or call done() -- instead it would time out. Luckily, filer has a helpful community around it. I saw someone was having a similar issue to mine where their Promise function wouldn't hit the done() block either. Lucky for them - and me - someone commented that done() was going to be deprecated anyways and provided a different strategy to tackling the problem. Using this information, I was able to finally fix my test case and create a pull request for it in hopes of it getting merged in.


The Pull Request

I also learned about what happens after the actual coding. I had my code reviewed, and reviewed someone elses code. I used Slack to ask questions and help others with their questions. The community aspect behind working on Open Source projects is really appealing to me.

The open source method of working as a team was a really fun experience for me and I really enjoyed it. I'm excited to continue contibuting to open source projects in the future - maybe even starting one of my own.

Wednesday, September 12, 2018

How 'chmod' Works In Node.js

Everyone experienced with a Linux environment should be familiar with the chmod command. Whether you're an administrator setting permissions for your users or a developer creating files through your Node.js server, this simple command will help you protect your restricted files from any unauthorized user.

In this blog post, I hope to cover the difference between chmod and fchmod and how they can be used in Node.js to work with your server.


chmod vs fchmod

To use these commands in Node.js, you must access them through the File System module's API.

The chmod and fchmod functions ran on a Node.js server are actually calls to the Linux versions by the same names. In standard Node.js fashion, the chmod commands are executed asynchronously and therefore require a callback function to be used as a parameter. Apart from the callback, the other two parameters of the functions remain the same.

The two commands follow a similar syntax. The only differences being chmod using a path to a file while fchmod using a file descriptor.


// chmod.js
// fs.chmod(path,mode,callback)
// path <string, Buffer, or URL>
// mode <integer>
// callback <Function> => err <Error>

const fs = require('fs');
fs.chmod('private.txt', 0o740, (err) => {
if (err) throw err;
  console.log('[chmod] Success');
});


// fchmod.js
// fs.fchmod(fd,mode,callback)
// fd <integer>
// mode <integer>
// callback <Function> => err <Error>

const fs = require('fs');
fs.open('private.txt', 'r', (err, fd) => {
  if (err) throw err;
  fs.fchmod(fd, 0o740, (err) => {
    if (err) throw err;
    console.log('[fchmod] Success');
  });
});


Note

If you use fs.open to create a file, you can also set the permissions inline by using the optional mode parameter. For example:

fs.open('newfile.txt', 'a', 0o740, (err, fd) => {...});


Promises

With the introduction of Promises into Node.js, v10.0.0 provided us with a Promise version of using the chmod command asynchronously.

// chmodPromises.js
// fsPromises.chmod(path,mode)
// path <string, Buffer, or URL>
// mode <integer>

const fs = require('fs');
const fsPromises = fs.promises;
fsPromises.chmod('private.txt', 0o740)
  .then(() => console.log('[chmod Promises] Success'));


Synchronization

Since both functions run asynchronously, you may run into a bit of trouble if you need them to run synchronously. Node.js provides a synchronous alternative to both functions. To run chmod and fchmod synchronously, you can use the fs.chmodSync and fs.fchmodSync commands respectively. These commands, being synchronous, do not require a callback function. Any error checking will have to be done manually.


// chmodSync.js
// fs.chmodSync(path,mode)
// path <string, Buffer, or URL>
// mode <integer>

const fs = require('fs');
fs.chmodSync('private.txt', 0o740);
console.log('[chmodSync] Success');


// fchmodSync.js
// fs.fchmodSync(fd,mode)
// fd <integer>
// mode <integer>

const fs = require('fs');
fs.open('private.txt', 'r', (err, fd) => {
  if (err) throw err;
  fs.fchmod(fd, 0o740);
  console.log('[fchmodSync] Success');
});


Note

Node.js provides a few alternatives to how to input a file mode for the chmod and fchmod commands. The file system provides you with a few constants to use in place of manually inputing octal numbers.

Constant Octal
fs.constants.S_IRUSR 0o400
fs.constants.S_IWUSR 0o200
fs.constants.S_IXUSR 0o100
fs.constants.S_IRGRP 0o40
fs.constants.S_IWGRP 0o20
fs.constants.S_IXGRP 0o10
fs.constants.S_IROTH 0o4
fs.constants.S_IWOTH 0o2
fs.constants.S_IXOTH 0o1