Skip to content

Commit

Permalink
feat(utils): new exports and rootDir breaking change
Browse files Browse the repository at this point in the history
- Added a new function `dependsOn` and a new interface `DependsOnOptions`.
- **BREAKING CHANGE**: When the argument or an option `rootDir` is given as relative path, `getConfigDirname()` of `@haetae/core` is joined with the `rootDir`.
  • Loading branch information
jjangga0214 committed Aug 22, 2022
1 parent cc0c008 commit cd79307
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 75 deletions.
5 changes: 5 additions & 0 deletions .changeset/utils-0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@haetae/utils': patch
---

Added a new function `dependsOn` and a new interface `DependsOnOptions`.
5 changes: 5 additions & 0 deletions .changeset/utils-rootdir-joined-with-configdirname.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@haetae/utils': patch
---

**BREAKING CHANGE**: When the argument or an option `rootDir` is given as relative path, `getConfigDirname()` of `@haetae/core` is joined with the `rootDir`.
11 changes: 9 additions & 2 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ export function toAbsolutePath({
}: ToAbsolutePathOptions): string {
// eslint-disable-next-line no-param-reassign
path = upath.normalize(path)
// eslint-disable-next-line no-param-reassign
rootDir = upath.resolve(rootDir) // It becomes an absolute path
if (upath.isAbsolute(path)) {
return path
}
// eslint-disable-next-line no-param-reassign
rootDir = upath.resolve(rootDir) // It becomes an absolute path
// eslint-disable-next-line no-param-reassign
rootDir = rootDir.endsWith('/') ? rootDir : `${rootDir}/`
const resolvedPath = upath.resolve(path)

if (resolvedPath.startsWith(rootDir) || `${resolvedPath}/` === rootDir) {
return upath.resolve(path)
}
return upath.join(rootDir, path)
}

Expand Down
26 changes: 26 additions & 0 deletions packages/common/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,32 @@ describe('toAbsolutePath', () => {
}),
).toBe('/root/dir/path/to/')
})
test('when `path` and `rootDir` are same', async () => {
expect(
toAbsolutePath({
path: '../',
rootDir: '../',
}),
).toBe(upath.join(process.cwd(), '..'))
expect(
toAbsolutePath({
path: '..',
rootDir: '../',
}),
).toBe(upath.join(process.cwd(), '..'))
expect(
toAbsolutePath({
path: '../',
rootDir: '..',
}),
).toBe(upath.join(process.cwd(), '..'))
expect(
toAbsolutePath({
path: '..',
rootDir: '..',
}),
).toBe(upath.join(process.cwd(), '..'))
})
})

describe('parseVersion', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@haetae/core": "workspace:~"
},
"dependencies": {
"@haetae/common": "workspace:~",
"globby": "^11",
"hasha": "^5.2.2",
"read-pkg": "^5.2.0",
Expand Down
5 changes: 0 additions & 5 deletions packages/utils/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
Utiliies for [**Haetae**](https://github.com/jjangga0214/haetae).

[![license](https://img.shields.io/badge/license-MIT-ff4081.svg?style=flat-square&labelColor=black)](https://github.com/jjangga0214/haetae/blob/main/LICENSE)
![test](https://img.shields.io/badge/test-jest-7c4dff.svg?style=flat-square&labelColor=black)
[![code style:airbnb](https://img.shields.io/badge/code_style-airbnb-448aff.svg?style=flat-square&labelColor=black)](https://github.com/airbnb/javascript)
[![code style:prettier](https://img.shields.io/badge/code_style-prettier-18ffff.svg?style=flat-square&labelColor=black)](https://prettier.io/)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-ffab00.svg?style=flat-square&labelColor=black)](https://conventionalcommits.org)
[![Commitizen friendly](https://img.shields.io/badge/Commitizen-cz_conventional_changelog-dd2c00.svg?style=flat-square&labelColor=black)](http://commitizen.github.io/cz-cli/)
![pr welcome](https://img.shields.io/badge/PRs-welcome-09FF33.svg?style=flat-square&labelColor=black)

🚧 WIP
68 changes: 56 additions & 12 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import globby from 'globby'
import childProcess from 'child_process'
import { getConfigDirname } from '@haetae/core'
import hasha from 'hasha'
import { parsePkg, toAbsolutePath } from '@haetae/common'

export { default as pkg } from './pkg'
export const pkg = parsePkg({ name: '@haetae/utils', rootDir: __dirname })

export interface GlobOptions {
rootDir?: string
Expand All @@ -15,6 +16,8 @@ export async function glob(
patterns: readonly string[],
{ rootDir = getConfigDirname(), globbyOptions = {} }: GlobOptions = {},
): Promise<string[]> {
// eslint-disable-next-line no-param-reassign
rootDir = toAbsolutePath({ path: rootDir, rootDir: getConfigDirname() })
// eslint-disable-next-line no-param-reassign
globbyOptions.cwd = globbyOptions.cwd || rootDir
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand All @@ -23,9 +26,7 @@ export async function glob(
globbyOptions.gitignore =
globbyOptions.gitignore === undefined ? true : globbyOptions.gitignore
const res = await globby(patterns, globbyOptions)
return res
.map((file) => (upath.isAbsolute(file) ? file : upath.join(rootDir, file)))
.map((file) => upath.normalize(file))
return res.map((f) => toAbsolutePath({ path: f, rootDir }))
}

export interface ExecOptions {
Expand Down Expand Up @@ -71,6 +72,8 @@ export async function hash(
files: readonly string[],
{ algorithm = 'sha256', rootDir = getConfigDirname() }: HashOptions = {},
): Promise<string> {
// eslint-disable-next-line no-param-reassign
rootDir = toAbsolutePath({ path: rootDir, rootDir: getConfigDirname() })
const hashes = await Promise.all(
[...files] // Why copy by destructing the array? => To avoid modifying the original array when `sort()`.
.sort()
Expand Down Expand Up @@ -101,17 +104,18 @@ export function graph({
rootDir = getConfigDirname(),
edges,
}: GraphOptions): DepsGraph {
// eslint-disable-next-line no-param-reassign
rootDir = toAbsolutePath({ path: rootDir, rootDir: getConfigDirname() })
const depsGraph: DepsGraph = {}
const toAbsolute = (file: string) =>
upath.isAbsolute(file) ? file : upath.join(rootDir, file)

for (let { dependents, dependencies } of edges) {
dependents = dependents
.map((dependent) => toAbsolute(dependent))
.map((dependent) => upath.normalize(dependent))
dependencies = dependencies
.map((dependency) => toAbsolute(dependency))
.map((dependency) => upath.normalize(dependency))
dependents = dependents.map((dependent) =>
toAbsolutePath({ path: dependent, rootDir }),
)
dependencies = dependencies.map((dependency) =>
toAbsolutePath({ path: dependency, rootDir }),
)

for (const dependent of dependents) {
depsGraph[dependent] = depsGraph[dependent] || new Set<string>()
for (const dependency of dependencies) {
Expand All @@ -121,3 +125,43 @@ export function graph({
}
return depsGraph
}

export interface DependsOnOptions {
dependent: string
dependencies: string[]
graph: DepsGraph
rootDir?: string
}

export function dependsOn({
dependent,
dependencies,
graph,
rootDir = getConfigDirname(),
}: DependsOnOptions): boolean {
// eslint-disable-next-line no-param-reassign
rootDir = toAbsolutePath({ path: rootDir, rootDir: getConfigDirname() })
// eslint-disable-next-line no-param-reassign
dependent = toAbsolutePath({ path: dependent, rootDir })
// eslint-disable-next-line no-param-reassign
dependencies = dependencies.map((d) =>
toAbsolutePath({
path: d,
rootDir,
}),
)

if (!graph[dependent]) {
return false
}
const queue = [...graph[dependent]]
for (const dependency of queue) {
if (dependencies.includes(dependency)) {
return true
}
if (graph[dependency]) {
queue.push(...graph[dependency])
}
}
return false
}
23 changes: 0 additions & 23 deletions packages/utils/src/pkg.ts

This file was deleted.

108 changes: 85 additions & 23 deletions packages/utils/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import upath from 'upath'
import { glob, graph } from '@haetae/utils'
import { glob, graph, dependsOn } from '../src/index'

describe('glob', () => {
test('basic usage', async () => {
Expand All @@ -23,52 +23,114 @@ describe('glob', () => {
describe('graph', () => {
test('basic usage', () => {
const result = graph({
rootDir: '<rootDir>',
rootDir: '/<rootDir>',
edges: [
{
dependents: ['path/to/foo.ts'],
dependencies: ['path/to/bar.ts', 'path/to/baz.ts'],
dependents: ['path/to/a.ts'],
dependencies: ['path/to/b.ts', 'path/to/c.ts'],
},
],
})

expect(result).toStrictEqual({
'<rootDir>/path/to/foo.ts': new Set([
'<rootDir>/path/to/bar.ts',
'<rootDir>/path/to/baz.ts',
'/<rootDir>/path/to/a.ts': new Set([
'/<rootDir>/path/to/b.ts',
'/<rootDir>/path/to/c.ts',
]),
})
})

test('advanced usage', () => {
const result = graph({
rootDir: '<rootDir>',
rootDir: '/<rootDir>',
edges: [
{
dependents: ['path/to/foo.ts', 'path/to/foo2.ts'],
dependencies: ['path/to/bar.ts', 'path/to/baz.ts'],
dependents: ['path/to/a.ts', 'path/to/b.ts'],
dependencies: ['path/to/d.ts', 'path/to/e.ts', 'path/to/c.ts'],
},
{
dependents: ['path/to/foo2.ts', 'path/to/foo3.ts'],
dependencies: ['path/to/bar2.ts', 'path/to/baz2.ts'],
dependents: ['path/to/b.ts', 'path/to/c.ts'],
dependencies: ['path/to/f.ts', 'path/to/g.ts'],
},
],
})
expect(result).toStrictEqual({
'<rootDir>/path/to/foo.ts': new Set([
'<rootDir>/path/to/bar.ts',
'<rootDir>/path/to/baz.ts',
'/<rootDir>/path/to/a.ts': new Set([
'/<rootDir>/path/to/d.ts',
'/<rootDir>/path/to/e.ts',
'/<rootDir>/path/to/c.ts',
]),
'<rootDir>/path/to/foo2.ts': new Set([
'<rootDir>/path/to/bar.ts',
'<rootDir>/path/to/baz.ts',
'<rootDir>/path/to/bar2.ts',
'<rootDir>/path/to/baz2.ts',
'/<rootDir>/path/to/b.ts': new Set([
'/<rootDir>/path/to/d.ts',
'/<rootDir>/path/to/e.ts',
'/<rootDir>/path/to/f.ts',
'/<rootDir>/path/to/g.ts',
'/<rootDir>/path/to/c.ts',
]),
'<rootDir>/path/to/foo3.ts': new Set([
'<rootDir>/path/to/bar2.ts',
'<rootDir>/path/to/baz2.ts',
'/<rootDir>/path/to/c.ts': new Set([
'/<rootDir>/path/to/f.ts',
'/<rootDir>/path/to/g.ts',
]),
})
})
})

describe('dependsOn', () => {
const depsGraph = graph({
rootDir: '/<rootDir>',
edges: [
{
dependents: ['a.ts'],
dependencies: ['b.ts', 'c.ts'],
},
{
dependents: ['c.ts'],
dependencies: ['d.ts'],
},
{
dependents: ['d.ts', 'e.ts'],
dependencies: ['f.ts'],
},
],
})
test('direct dependency', () => {
expect(
dependsOn({
dependent: '/<rootDir>/a.ts',
dependencies: ['/<rootDir>/c.ts'],
graph: depsGraph,
rootDir: '/<rootDir>',
}),
).toBe(true)
})
test('transitive dependency', () => {
expect(
dependsOn({
dependent: '/<rootDir>/a.ts',
dependencies: ['/<rootDir>/x.ts', '/<rootDir>/f.ts'],
graph: depsGraph,
rootDir: '/<rootDir>',
}),
).toBe(true)
})
test('non-existent dependency', () => {
expect(
dependsOn({
dependent: '/<rootDir>/a.ts',
dependencies: ['/<rootDir>/non-existent.ts'],
graph: depsGraph,
rootDir: '/<rootDir>',
}),
).toBe(false)
})
test('non-existent dependent', () => {
expect(
dependsOn({
dependent: '/<rootDir>/non-existent.ts',
dependencies: ['/<rootDir>/c.ts'],
graph: depsGraph,
rootDir: '/<rootDir>',
}),
).toBe(false)
})
})
7 changes: 0 additions & 7 deletions packages/utils/test/pkg.test.ts

This file was deleted.

5 changes: 4 additions & 1 deletion packages/utils/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
"tsBuildInfoFile": "../../.build-cache/utils.tsbuildinfo"
},
"include": ["src"],
"references": [{ "path": "../core/tsconfig.build.json" }]
"references": [
{ "path": "../core/tsconfig.build.json" },
{ "path": "../common/tsconfig.build.json" }
]
}
5 changes: 4 additions & 1 deletion packages/utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"extends": "../../tsconfig.json",
"references": [{ "path": "../core/tsconfig.build.json" }]
"references": [
{ "path": "../core/tsconfig.build.json" },
{ "path": "../common/tsconfig.build.json" }
]
}
Loading

0 comments on commit cd79307

Please sign in to comment.