Change default shell for new users

2019-10-24

If you have a system with lots of new users, you probably want to set the default shell to the one that most users prefer.

If you're using the useradd command, you can set default options in the file /etc/default/useradd.

Editing this file can be done by using useradd -D ...:

# set default shell for new users to bash
useradd -D -s /bin/bash

Check here for more information.


Convert JSON to table type

2019-10-23

The function json_populate_record can be used to cast a JSON object to a table type:

CREATE TABLE foo(bar int);

SELECT  *
FROM    json_populate_record(NULL::foo, '{"bar": 42}')
+-------+
| bar   |
|-------|
| 42    |
+-------+

This can also be used to insert into the table:

INSERT INTO foo
SELECT *
FROM   json_populate_record(NULL::foo, '{"bar": 42}')

Use multiple files for docker-compose config

2019-10-18

You can specify one or multiple config files for docker-compose with the -f flag:

# one file
docker-compose -f docker-compose.yml up -d
# multiple files
docker-compose -f docker-compose.yml -f docker-compose.tests.yml up -d

Be sure to specify the config files before the sub-command:

# invalid
docker-compose ps -f docker-compose.yml
# valid
docker-compose -f docker-compose.yml ps

Get granted roles with psql

2019-10-16

With psql, there is an easy way to check which roles are granted to a role: \du

henk=> CREATE ROLE accounting;
CREATE ROLE
henk=> CREATE ROLE alex;
CREATE ROLE
henk=> GRANT accounting TO alex;
GRANT ROLE
henk=> \du accounting
             List of roles
 Role name  |  Attributes  | Member of
------------+--------------+-----------
 accounting | Cannot login | {}

henk=> \du alex
              List of roles
 Role name |  Attributes  |  Member of
-----------+--------------+--------------
 alex      |              | {accounting}

Understanding Javascript at a low level

2019-10-15

Did you ever ask yourself how Javascript works under the hood? It's important to understand how the language we're working with works on a lower level.

 Top level view of the Javascript engine

  • Receive source code
  • Parse the code and produce an Abstract Syntax Tree (AST)
  • Interpret as byte code and execute it
  • The profiler checks for optimisations at run-time
  • The compiler creates optimized code and replaces it with the byte code

Javascript Engine

What does the parser do?

Parser

A parser takes the source code and creates an AST. First, the parser splits the source code into tokens. There are different kinds of tokens, e.g. let and new are keywords, while + is an operator.

The tokens are then used to build the AST. If something unexpected is found, a SyntaxError is thrown.

A SyntaxError is thrown when the Javascript engine finds a piece of codes that don't belong to the language syntax.

Example

Let's try out the parser (using this website).

> var answer = 6 * 7;
[
    {
        "type": "Keyword",
        "value": "var"
    },
    {
        "type": "Identifier",
        "value": "answer"
    },
    {
        "type": "Punctuator",
        "value": "="
    },
    {
        "type": "Numeric",
        "value": "6"
    },
    {
        "type": "Punctuator",
        "value": "*"
    },
    {
        "type": "Numeric",
        "value": "7"
    },
    {
        "type": "Punctuator",
        "value": ";"
    }
]

 Abstract Syntax Tree (AST)

It's a graph (data structure) that represents a program.

It's used in:

  • Javascript Engine
  • Bundlers: Webpack, Rollup, Parcel
  • Transpilers: Babel
  • Linters: ESLint, Prettify
  • Type Checkers: Typescript, Flow
  • Syntax Highlighters

You can check the generated AST in the AST Explorer.

Below is an example on how to add an ESLint rule.

export default function(context) {
  return {
    VariableDeclaration(node) {
    	// const variable type
     	if (node.kind === "const") {
        	const declaration = node.declarations[0];
          	
          	// make sure that the value it's a number
          	if (typeof declaration.init.value === "number") {
            	 if (declaration.id.name !== declaration.id.name.toUpperCase()) {
                   	context.report({
                      	node: declaration.id,
                      	message: "The constant name should be in uppercase",
                      	fix: function(fixer) {
                         	return fixer.replaceText(declaration.id, declaration.id.name.toUpperCase()) 
                        }
                    })
                 }
            }
        }
    }
  };
};

 Example using AST to extend an ESLint rule without fix option

Example using AST to extend an ESLint rule without fix option

 Example using AST to extend an ESLint rule with fix option

Example using AST to extend an ESLint rule with fix option


Object preventExtension vs seal vs freeze

2019-10-11

ECMAScript 5 introduced new Object methods to Javascript. Among them preventExtensions, seal, freeze methods will be compared to each other.

preventExtensions

An object called by this method can't have any new properties being added.

Example

let person = {
  name: "Agustin",
  age: 27,
};

Object.preventExtensions(person);
Object.isExtensible(person); // return false

person.surname = "Ramirez";
console.log(person.surname); // return undefined

person.name = "Maria";
console.log(person); // return { name: "Maria", age: 27 }

delete person.age;
console.log(person); // return { name: "Maria" }

seal

An object called by this method can not have any new properties being added or current properties deleted.

Example

let person = {
  name: "Agustin",
  age: 27,
};

Object.seal(person);
Object.isSealed(person); // return true

// In strict mode this will throw a `TypeError`
person.foo = "something";
console.log(person.foo); // return undefined

person.name = "Maria";
console.log(person); // return { name: "Maria", age: 27 }

delete person.age;
console.log(person); // return { name: "Maria", age: 27 }

Object.defineProperty(person, "name", {
  get: () => "Juan",
}); // Throw TypeError

console.log(person); // return { name: "Maria", age: 27 }

freeze

An object called by this method can not have any further changes done to it.

Example

let person = {
  name: "Agustin",
  age: 27,
};

Object.freeze(person);
Object.isFrozen(person); // return true

person.name = "Maria";
console.log(person); // return { name: "Agustin", age: 27 }

shallow only

All of these methods only work on object properties shallowly, meaning that just work with the direct property references.

let person = {
  name: "Agustin", // Prevented, Sealed and Frozen
  age: 27, // Prevented, Sealed and Frozen
  address: {
    // Un-prevented, un-sealed and un-frozen
    country: "Argentina", // Un-prevented, un-sealed and un-frozen
    city: "Corrientes", // Un-prevented, un-sealed and un-frozen
  },
};

Feature matrix

Feature default preventExtensions seal freeze
add new properties
remove existing properties
change existing property values

`diff.orderFile`: order your `git diff` output smart!

2019-10-10

Working on a project, you might consider that one folder is more important than others. For example, src folder might be more relevant to you as a developer than doc, test, or samples, you name it. Or you may want source files to be listed first, e.g. *.c, *.go...

To order the list of files in git diff output, one may use git's diff.orderFile option.

If you are working with PostgreSQL for example, you may want such an order:

src/include/* 
src/common/* 
src/port/* 
config/* 
src/makefiles/* 
src/template/* 
src/backend/* 
src/fe_utils/* 
src/bin/* 
src/interfaces/libpq/* 
src/pl/* 
contrib/* 
src/interfaces/* 
doc/* 
src/test/*

To achieve this:

  • create a file with the proper list, e.g. .gitorderfile
  • run git config diff.orderFile .gitorderfile

You're done!