teleren/devto huggingface dataset:
Git Hooks without extra dependencies like Husky in Node.js project
Tags: node, git, javascript
Published: 2021-02-22 02:47:41

---
title: Git Hooks without extra dependencies like Husky in Node.js project
published: true
description: Setup Git Hooks without any dependencies
tags:  nodejs,git,javascript
---

Git 2.9+ supports [`core.hooksPath`](https://git-scm.com/docs/githooks) for local git hooks, so we do not need extra dependencies like [husky](https://github.com/typicode/husky).

[lint-staged](https://github.com/okonet/lint-staged) recommented to use with [husky](https://github.com/typicode/husky).
However, [husky v5.0.0](https://github.com/typicode/husky/releases/tag/v5.0.0) is licesed under [The Parity Public License](https://paritylicense.com/).

- [When will version 5 be MIT license again? · Issue #857 · typicode/husky](https://github.com/typicode/husky/issues/857)

We can use `core.hooksPath` instead of [husky](https://github.com/typicode/husky).

:memo: [husky v5](https://github.com/typicode/husky) also use `core.hooksPath` internally. It is a wrapper for some commands and provide extra features.

## Setup

Setup for [lint-staged](https://github.com/okonet/lint-staged).

- 1. mkdir `.githooks`
- 2. Create `.githooks/pre-commit` and put the following content.

`.githooks/pre-commmit`:

```
#!/bin/sh
npx --no-install lint-staged
```

- 3. Add [`prepare`](https://docs.npmjs.com/cli/v7/using-npm/scripts#prepare-and-prepublish) lifecycle script to `package.json`

```json
  "scripts": {
    "prepare": "git config --local core.hooksPath .githooks"
  },
```

Complete to setup! :tada:

This `prepare` hooks is exected when the user has run `npm install` or `yarn install`.


:memo: You can also use `postinstall` hook.
However, If your package is not `private` and you're publishing it on a registry like npmjs.com, you should not use `postinstall` scripts.

See also [Husky's documentation](https://typicode.github.io/husky/#/?id=install).

## Pros

- no dependencies

## Cons

- not available add command like `husky add`
- can not run local hooks and global hooks at once(husky <=v4 and simple-git-hooks allow it because these does not use `core.hooksPath`)


## Example

It is an example repository.

- [azu/githook-lint-staged-example: Git 2.9+(`core.hooksPath`) + Lint Staged without extra dependencies.](https://github.com/azu/githook-lint-staged-example)

## Note

Some environment like [Cloudflare Pages](https://pages.cloudflare.com/) or [Heroku](https://heroku.com/) clone the repository without `.git` directory for deploying the repository. 

In the env, you will see the following errors

```
fatal: Not a git repository
```

You can avoid this error by following changes.

```diff
  "scripts": {
-    "prepare": "git config --local core.hooksPath .githook"
+    "prepare": "git config --local core.hooksPath .githook || echo 'Can not set git hooks'"
  },
```

See also [Disable hooks in CI - Husky](https://typicode.github.io/husky/#/?id=disable-hooks-in-ci).
Keyoxide Proof
Published: 2021-02-22 02:26:26

This is an OpenPGP proof that connects [my OpenPGP key](https://keyoxide.org/010C913AD4BA95D4CA69047986A9D074C35DD7C4) to [this dev.to account](https://dev.to/jshrack). For details check out https://keyoxide.org/guides/openpgp-proofs

[Verifying my OpenPGP key: openpgp4fpr:010C913AD4BA95D4CA69047986A9D074C35DD7C4]
Determine the Maximum Number
Tags: number, javascript, maximum, function
Published: 2021-02-22 02:09:33

I overshot the goal on a homework assignment and came up with a function that would handle edge cases. It was just supposed to take in three distinct numerical inputs and determine which one was the largest. But I built my function to account for the possibility that two or even all three of the numbers might be identical, plus the possibility that one or all of the inputs might be non-numerical. It may have been overkill, but I’m pretty proud of how much I nerded out here.

{% gist https://gist.github.com/jtreeves/c7e40a8cd19f5a26fdca5696a41e7abb %}
Creating an instance of GitLab with Reclaim Cloud
Published: 2021-02-22 02:06:56

# Background

GitHub is a platform that is used for version control and collaboration of code. It allows you to work with others on a team so that you can develop projects without being in the same place at the same time. Though a very useful tool, GitHub is most useful when working in small groups or teams. GitLab, on the other hand, allows you to use the same features as GitHub, but is more tailored towards bigger organization. 

# Implementation
## Reclaim Cloud Sign Up
The sign-up process for reclaim is very simple. Once you enter an email and password, you will be granted access to your account. [Sign up here](https://reclaim.cloud/signup/)
 
## Configuration
Before you are able to configure your environment through Reclaim Cloud, you must increase the minimum cloudlets so that the server is able to allocate the proper amount of resources to properly run. This can be done through clicking the "Change Environment Topology" button and dragging the slider in the middle of the page to 32 cloudlets.

## Usage
Once you have increased the number of cloudlets, you will be able to click the link under DevOps Lab, as shown in the picture below.

![GitLab Directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e23sxqjd7wwvh2kcp04r.PNG)

Once you have entered into GitLab, you are now able to use all features that are available on the platform. From security to CI, GitLab provides a number of features that GitHub does not. The number of features that appear on the left sidebar gives GitLab an advantage over GitHub.

Overall, GitHub and GitLab are both very useful platforms when they are used in the most appropriate setting.

[Video explanation](https://youtu.be/A1rdJJXsUVI)
Triple All the Numbers
Tags: number, triple, javascript
Published: 2021-02-22 02:05:20

This function takes in an array and returns a new array containing each element from the first array after they were multiplied by three. Note the comments interspersed in the code. They act as guideposts, explaining each step of the code in pseudocode to make it easier for the non-coder to understand.

{% gist https://gist.github.com/jtreeves/195b2f2c92162aac856188177c0888c8 %}
Find the Mode of Intervals
Tags: python, statistics, mode, spread
Published: 2021-02-22 02:01:57

A simple Python function for calculating the MQR, a nifty statistical measure of spread that I came up with one night.

I was annoyed that every measure of central tendency had a corresponding measure of spread—except mode. Mean has standard deviation; median has interquartile range. But what about mode? So for the sake of parity, I made one up.

I call it the Minimal Quintile Range (or MQR), which provides the length of the smallest interval that contains at least a fifth of the data in a set. In other words, the mode of intervals.

{% gist https://gist.github.com/jtreeves/fb9c5c9565e63ab4e34ec3d8369448b5 %}
Push Object to a Paired Array
Tags: object, array, pair, push
Published: 2021-02-22 01:49:54

Pushing an object from one array into another array’s object is tricky, especially if you don’t know how many elements are in each array or where each one might be found. If both objects in question happen to share a common key-value pair, then you can use this approach. You’ll end up giving the main array’s object a new key and setting its value to the other array’s object. You can achieve all of that with two `for` loops that iterate over both arrays separately plus an `if` conditional.

{% gist https://gist.github.com/jtreeves/accfc41a2a768dc16b18f51b6287fcca %}

For more details about this technique (and alternative solutions to its underlying problem), check out [this Stack Overflow answer](https://stackoverflow.com/questions/39841513/how-to-combine-two-array-objects-if-a-key-value-matches-in-both-arrays) that ultimately put me on the right track.
Using a heap to find the minimum cost to modify an array
Tags: javascript, algorithms
Published: 2021-02-22 01:39:11

 Javascript doesn't have a heap data structure like java does `PriorityQueue` so an external library or an own implementation is needed. 


```javascript
const minCost = (numbers) => {
    return Math.min(up(numbers, numbers.length), down(numbers, numbers.length))
}

const down = (numbers, length) => {
    let sum = 0
    let diff = 0

    let minQueue = new MinBinaryHeap()

    for(let i = 0; i < length; i++){
        // console.log(minQueue.getTop())
        if(!minQueue.isEmpty() && minQueue.getTop() <= numbers[i]){
            diff = numbers[i] - minQueue.getTop()
            sum += diff
            minQueue.getTopElementAndReorder()
            minQueue.insertElement(numbers[i])
        }
        minQueue.insertElement(numbers[i])
    }
    return sum
}

const up = (numbers, length) => {
    let sum = 0
    let diff = 0

    let maxQueue = new MaxBinaryHeap()

    for(let i = 0; i< length; i++){
        if(!maxQueue.isEmpty() && maxQueue.getTop() >= numbers[i]){
            diff = maxQueue.getTop() - numbers[i]
            sum += diff
            maxQueue.getTopElementAndReorder()
            maxQueue.insertElement(numbers[i])
        }
        maxQueue.insertElement(numbers[i])
    }
    return sum
}
```

This algorithm calculates the minimum amount of changes that are needed to make an array ascending or descending. 

Each value in the array is added to the binary heap then if there is a larger or lower (correspondingly) number in the heap than the current value then the difference between the values is accumulated in the sum variable. 

Using the heap allows for storing and retrieveing elements relatively fast and always in a sorted manner. 

[Here is my max binary heap and min binary heap `priority queue` implementation] (https://github.com/SantiagoSalazarPavajeau/coding_challenges/commit/512bb810a23360e25a53d0db585595753fc47cd8)
API and Database Playing Together
Tags: api, database, promise
Published: 2021-02-22 01:36:21

I was in Promises Hell for about three days until I finally came up with this code. The problem: I needed to query my local database, then use the result from that query to make an API call, then render the results of both the database query and the API call on an EJS views page. This did not go as smoothly as I would have liked. The main hurdle was that my original code required making multiple API calls before moving on to the render stage, which landed me in Promises Hell. My solution was to parse some info from my database query to create a single string that I could feed into my API call, so I only needed to make one call instead of multiple (potentially hundreds) of calls each time. Then I was able to neatly package it all up and send it to my `rated` EJS views page. Oh, complicated routes, you certainly can be fun.

{% gist https://gist.github.com/jtreeves/8495c1d98a9cf3b0a32eebdbcda0af7a %}
Code Snippets with Gist
Tags: gist, github, code, snippet
Published: 2021-02-22 01:34:08

[Gist](https://gist.github.com) is a cool resource. It’s for sharing code snippets anywhere online. It’s great if you want to share a few lines of your code instead of every document ever in your GitHub repo.

It’s related to GitHub, but in a really weird way. It’s a subsidiary or vertical of GitHub, so if you have a GitHub account (which we all do), then you automatically have a Gist account. Annoyingly, it’s difficult to access Gist from GitHub, but easy to access GitHub from Gist. To find your Gist from your GitHub, you need to click on your profile icon, then scroll down to “Your gists” in the dropdown menu. There’s no other place to find it. Additionally, compare your Gist profile and your GitHub profile: If you view [your Gist profile](https://gist.github.com/jtreeves), there’s a link to view [your GitHub profile](https://github.com/jtreeves) right below your profile pic and intro text, but not the other way around. Why? I have no idea, but I feel like this is a kind of annoying flaw.

Also annoyingly, albeit this time because of Slack: You can’t embed a Gist snippet inside a Slack post (instead of creating a code snippet in Slack), but you can include a link to [your Gist snippet](https://gist.github.com/jtreeves/accfc41a2a768dc16b18f51b6287fcca).

The major benefit of Gist code snippet’s over Slack’s code snippets is that you can use a Gist version _anywhere_, whereas Slack’s versions can only be used on Slack.
The Joys of Slack
Tags: slack
Published: 2021-02-22 01:31:54

If you’re new to Slack and aren’t quite sure how to navigate all its functionalities, this guide might help! Included: tips on how to pep up your posts with different styles, a hands-holding guide to replying to a post in its thread as opposed to just in the general channel, and a note about emojis.

POSTS

*   new line: `shift` + `enter` (without the `shift`, it’ll post)
*   post: `enter` (no `shift` this time)
*   keywords: surround text with backticks (e.g., `keyword text`)
*   bold: surround text with asterisks (e.g., *bolded text*)
*   italicize: surround text with underscores (e.g., _italicized text_)
*   lists: begin message with the numeral one ( 1 ) for ordered lists or an asterisk ( * ) for unordered lists
*   block quote: begin line with a bracket ( &gt; ); get out of it by creating a new line
*   inline code: begin with triple backticks ( ``` ); get out of it by closing it with triple backticks
*   code snippet: click `lightning bolt` in new message, then select `create a code or text snippet`, then select what language to use in the `type` dropdown menu, then paste in the editor

THREADS

*   reply to a post by clicking the `chat bubble` icon to go to the thread
*   post your comment as a reply in that specific thread, as opposed to in the general channel stream

REACTIONS

*   use emojis to quickly reply to a message without using text
*   have everyone click on a certain emoji to indicate they’ve completed a task

MENTIONS

*   grab someone’s attention by using the “at” symbol ( @ ) before their username
*   users get notifications of their mentions

MESSAGES

*   send a private message to specific user by going to the `All DMs` link in the top left of the main sidebar
*   type a user into the search bar to pull them up, then send them your message

CHANNELS

*   organize discussions into different sections, based on their primary focus
*   searchable
*   join or leave as needed
*   all your channels appear in your sidebar under `channels`
*   stars: star channels to pull them out of the general `channels` section of the sidebar and into a new `starred` section of the sidebar
*   pins: pin important messages in threads, so they’ll always be accessible via the `pin` icon in the top left corner of a channel’s stream

INTEGRATIONS

*   you can link up third-party platforms like Dropbox or Google Calendar

_MORE INFO:_

[https://slack.com/resources/using-slack/how-to-use-slack](https://slack.com/resources/using-slack/how-to-use-slack)

[https://slack.com/help/articles/202288908-Format-your-messages](https://slack.com/help/articles/202288908-Format-your-messages)

[https://slack.com/help/articles/204145658-Create-a-snippet](https://slack.com/help/articles/204145658-Create-a-snippet)
Best way to create GraphQL APIs ?? | NestJS GraphQL Tutorial
Tags: showdev, graphql, nestjs, node
Published: 2021-02-22 01:07:39

---
title: Best way to create GraphQL APIs ?? | NestJS GraphQL Tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n54sztfcmsgb0qmizsed.jpg
published: true
description: In this video I walk you through one of the best ways to create a GraphQL API utilizing the Nestjs framework, TypeORM, and a few other packages!
tags: showdev, graphql, nestjs, node
---

[In this video](https://youtu.be/geYvdbpo3cA) I walk you through how to create a new GraphQL server and API from scratch utilizing the NestJS framework. This is, in my opinion, one of the best ways to do it!

We'll also cover multiple topics including database integration with TypeORM, queries and mutations, validation, as well as some techniques to help you develop these as **FAST** as possible!  

Let me know what you think :lion:

{% youtube geYvdbpo3cA %}
Objects De-structuring...  
Tags: javascript, codenewbie
Published: 2021-02-22 01:06:08

To start, Object **De-structuring** is a way you can basically extract values from a *Object* and put them inside individual variables. 

## Example:

```javascript
const car = {
  make: 'Honda',
  model: 'Civic'
};

let { make, model } = car;

console.log(make);
console.log(model);

//Honda
//Civic

```

We define an *Object* called *car* with a few properties, called *make* & *model*. So we can extract the properties from this *Object* and set them to individual variables using **{ }** this syntax right here.

Basically, we are just defining **2** new variables *make* & *model* and setting them to the values of the property names inside of the *Object*.

## You Can Also Set Default Values:

```javascript
const car = {
  make: 'Honda',
  model: 'Civic'
};

let { make, model, year = 'Unknown' } = car;

console.log(make);
console.log(model);
console.log(year);

//Honda
//Civic
//Unknown

```

So.. The *car* *Object* does not contain the *year* property but we can still set a *year* variable and set it to **Unknown**.
But if we define a *year* property in the *Object* it will override the **Default Value** by the actual **car** property.

## We Can Do Something Very Similar Using Functions:

```javascript
const car = {
  make: 'Honda',
  model: 'Civic'
};

function carDataSheet({ make, model }) {
  console.log(`The Car is a ${make} ${model}! `);
}

  carDataSheet(car);

//The Car is a Honda Civic!

```
I feel lost at **function** sometimes.. But, its actually really simple. So with **carDataSheet(car)** we are passing in the *Object*, and have set a *parameter* **({make,model})**. And its really doing the same thing as above..
So we are extracting the *make* & *model* property of this *Object* & setting it to the variables inside of the **function**. That is basically *Object De-structuring*  in a nut shell!!
ลองเขียน Must ฟังก์ชันในแบบ generic ของ Go
Tags: go
Published: 2021-02-22 00:56:00

หลังจากที่ Proposal เรื่อง Generic (Type Parameters) https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md ผ่านแล้ว อีกประมาณ 1 ปีก็จะออกมาให้ใช้ แต่ในระหว่างนี้เราก็ลองเล่นจาก branch `dev.go2go` ได้ก็เลยได้หัดคิดว่าโค้ดแบบไหนที่ก่อนหน้านี้ที่เราใช้บ่อยๆ สามารถเอามาเรื่อง generic มาปรับปรุงได้ วันนี้เลยยกฟังก์ชัน Must ที่เราเห็นบ่อยๆในหลายๆ package มาลองเขียนด้วย generic ดู

ตัวอย่างเช่นใน package [`html/template`](https://golang.org/pkg/html/template/#Must) จะมีฟังก์ชัน `Must` หน้าตาแบบนี้อยู่

```go
func Must(t *Template, err error) *Template
```

ใน document เขียนบอกเอาไว้ว่า

>  Must is a helper that wraps a call to a function returning (*Template, error) and panics if the error is non-nil. It is intended for use in variable initializations such as 

```go
var t = template.Must(template.New("name").Parse("html"))
```

จะเห็นว่ามันก็เป็นฟังก์ชันที่รับผลลัพธ์จากการเรียกฟังก์ชันที่ return `(*Template, error)` แล้วเช็คว่าถ้ามี error แล้วจะ panic ถ้าไม่มีก็ได้ `*Template` กลับออกมาให้นั่นเอง เพื่อทำให้เราไม่ต้องเขียน if แบบนี้เอง

```go
var t, err = template.New("name").Parse("html")
if err != nil {
        panic(err)
}
```

อีกเหตุผลเพราะว่าเราเขียนแบบนี้ในตอนที่เราเรียกฟังก์ชันแล้วกำหนดค่าให้ตัวแปรใน package scope ไม่ได้ด้วยนั่นเอง

อย่างไรก็ตาม ถ้าเราคิดดีๆจะเห็นว่ามีอีกตั้งหลายครั้งที่เราเรียกฟังก์ชันแล้วได้ผลลัพธ์กลับออกมาพร้อม error เช่นตอนเรียก `json.Marshal`

```go
b, err := json.Marshal(map[string]string{"msg": "Hello"})
if err != nil {
        panic(err)
}
```

หรือตอนเรียก `strconv.Atoi`

```go
num, err := strconv.Atoi("30")
if err != nil {
        panic(err)
}
```

ซึ่งตอนที่ยังไม่มี generic เราต้องเขียน Must แยกเลยสำหรับแต่ละ type เช่นต้องมี `Must([]byte, error)` สำหรับเคส `json.Mashal` และ `Must(int, error)` สำหรับเคส `strconv.Atoi`

## เขียน Must แบบ Generic
ทีนี้เมื่อไหร่ก็ตามที่ Go รองรับ generic แล้วเราสามารถเขียน Must แค่รอบเดียวรองรับทั้ง 3 กรณีด้านบนได้เลยแบบนี้

```go
func Must[T any](v T, err error) T {
	if err != nil {
		panic(err)
	}
	return v
}
```

คือเรากำหนด type parameter `[T any]` แล้วเอา type `T` ไปใช้เป็น parameter แรก แทนที่จะกำหนด type เจาะจงเองแบบก่อนหน้านี้

ทำให้เราใช้ `func Must[T any](v T, err error) T` ที่เขียนแค่ครั้งเดียวนี้ได้กับที่ 3 กรณีด้านบนแบบนี้

```go
var t = Must(template.New("name").Parse("html"))
var b = Must(json.Marshal(map[string]string{"msg": "Hello"}))
var num = Must(strconv.Atoi("30"))
```

## ขอฝาก Buy Me a Coffee
สำหรับท่านใดที่อ่านแล้วชอบโพสต์ต่างๆของผมที่นี่ ต้องการสนับสนุนค่ากาแฟเล็กๆน้อยๆ สามารถสนับสนุนผมได้ผ่านทาง Buy Me a Coffee คลิ๊กที่รูปด้านล่างนี้ได้เลยครับ

<a href="https://www.buymeacoffee.com/weerasak" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 60px !important;width: 217px !important;" ></a>

ส่วนท่านใดไม่สะดวกใช้บัตรเครดิต หรือ Paypal สามารถสนับสนุนผมได้ผ่านทาง PromptPay โดยดู QR Code ได้จากโพสต์ที่พินเอาไว้ได้ที่ Page DevDose ครับ https://web.facebook.com/devdoseth

ขอบคุณครับ 🙏
A randomly failing test is a failing test
Tags: testing
Published: 2021-02-22 17:11:28

---
title: A randomly failing test is a failing test
published: true
date: 2021-02-22 00:00:00 UTC
tags: testing
canonical_url: https://jhall.io/archive/2021/02/22/a-randomly-failing-test-is-a-failing-test/
---

You’ve just spent several hours building an awesome new feature for your application. You wrote automated tests for it. You manually tested everything in the staging environment. You even asked your colleague to stress-test it for you, and they couldn’t make it crash. Perfect!

Now you push it up to your version control system, and…

A test fails!

Not one of your new tests. An old test. Dagnabbit!

You must have introduced a regression somewhere along the line.

So you poke around. Maybe you roll back some things, or pull out the [git bisect](https://git-scm.com/docs/git-bisect) hammer. You can’t find the problem. Finally, out of frustration, you make some trivial change to your code, and push it to your VCS again. This time the tests pass.

!@#$%

This is the havoc wreaked by randomly failing tests.

A randomly failing test _is_ a failing test, and ought to be treated as one. Not only can it waste time, as in my example, it can often obscure some other failure. This means in actuality, a randomly failing test is often worse than _no test at all_.