Skip to content
This repository has been archived by the owner on Oct 10, 2022. It is now read-only.

Commit

Permalink
feat: detect js workspaces (#3)
Browse files Browse the repository at this point in the history
* feat(js-workspaces): detect js-workspaces

* chore: clean linting errors

* chore(js-workspaces): set interface keys at buildInfo level
  • Loading branch information
JGAntunes authored Mar 29, 2021
1 parent b445063 commit 0dbf74b
Show file tree
Hide file tree
Showing 11 changed files with 557 additions and 472 deletions.
852 changes: 385 additions & 467 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,9 @@
},
"engines": {
"node": ">=8.3.0"
},
"dependencies": {
"@npmcli/map-workspaces": "^1.0.3",
"read-pkg": "^5.2.0"
}
}
39 changes: 39 additions & 0 deletions src/context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const { resolve } = require('path')
const { cwd } = require('process')

const readPkg = require('read-pkg')

const getPackageJson = async function (dir) {
try {
const packageJson = await readPkg({ cwd: dir, normalize: false })
if (packageJson === undefined) {
return {}
}

return packageJson
} catch (error) {
return {}
}
}

const getContext = async function ({ projectDir = cwd(), rootDir } = {}) {
// Get the absolute dirs for both project and root
const absoluteProjectDir = resolve(cwd(), projectDir)
const absoluteRootDir = rootDir ? resolve(cwd(), rootDir) : undefined

// We only pass through the root dir if it was provided and is actually different
// from the project dir
const validRootDir = absoluteRootDir && absoluteRootDir !== absoluteProjectDir ? absoluteRootDir : undefined

// If rootDir equals projectDir we'll be getting the projectDir package.json
// Later on if we also need the projectDir package.json we can check for it
// and only perform one resolution
const rootPackageJson = await getPackageJson(rootDir || projectDir)
return {
projectDir: absoluteProjectDir,
rootDir: validRootDir,
rootPackageJson,
}
}

module.exports = { getContext }
33 changes: 33 additions & 0 deletions src/core.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
'use strict'

const mapWorkspaces = require('@npmcli/map-workspaces')

const getWorkspaceInfo = async function ({ rootPackageJson, projectDir, rootDir }) {
if (!rootPackageJson.workspaces) {
return
}

const workspacesMap = await mapWorkspaces({
cwd: rootDir || projectDir,
pkg: rootPackageJson,
})

const packages = [...workspacesMap.values()]
// The provided project dir is a workspace package
const isWorkspace = packages.find((path) => projectDir === path)

// The project dir is a collection of workspaces itself
const isRoot = !rootDir

if (isWorkspace || isRoot) {
return { isRoot, packages }
}
}

const buildInfo = async function (context) {
const workspaceInfo = await getWorkspaceInfo(context)
const jsWorkspaces = workspaceInfo ? { jsWorkspaces: workspaceInfo } : {}
return { ...jsWorkspaces }
}

module.exports = { buildInfo }
10 changes: 7 additions & 3 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
'use strict'

const mainFunction = function () {
return true
const { getContext } = require('./context')
const { buildInfo } = require('./core')

const getBuildInfo = async function (opts) {
const context = await getContext(opts)
return await buildInfo(context)
}

module.exports = { mainFunction }
module.exports = { getBuildInfo }
4 changes: 4 additions & 0 deletions test/fixtures/js-workspaces/not-in-workspace/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "not-in-workspace",
"version": "1.0.0"
}
7 changes: 7 additions & 0 deletions test/fixtures/js-workspaces/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "js-workspaces",
"version": "1.0.0",
"workspaces": [
"packages/*"
]
}
4 changes: 4 additions & 0 deletions test/fixtures/js-workspaces/packages/package-1/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "package-1",
"version": "1.0.0"
}
4 changes: 4 additions & 0 deletions test/fixtures/js-workspaces/packages/package-2/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "simple-package-json",
"version": "1.0.0"
}
4 changes: 4 additions & 0 deletions test/fixtures/simple-package-json/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "simple-package-json",
"version": "1.0.0"
}
68 changes: 66 additions & 2 deletions test/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,69 @@
const { resolve } = require('path')

const test = require('ava')

test('Template test', (t) => {
t.pass()
const { getBuildInfo } = require('../src/main')

const FIXTURES_RELATIVE_PATH = `${__dirname}/fixtures`
const FIXTURES_ABSOLUTE_PATH = resolve(FIXTURES_RELATIVE_PATH)

test('js-workspaces: project without package.json does not return workspaces info', async (t) => {
const { jsWorkspaces } = await getBuildInfo({
projectDir: `${FIXTURES_RELATIVE_PATH}/empty`,
})
t.is(jsWorkspaces, undefined)
})

test('js-workspaces: project without workspaces in package.json does not return workspaces info', async (t) => {
const { jsWorkspaces } = await getBuildInfo({
projectDir: `${FIXTURES_RELATIVE_PATH}/simple-package-json`,
})
t.is(jsWorkspaces, undefined)
})

test('js-workspaces: projectDir set to workspaces root returns workspace info and isRoot flag set to true', async (t) => {
const { jsWorkspaces } = await getBuildInfo({
projectDir: `${FIXTURES_RELATIVE_PATH}/js-workspaces`,
})
t.not(jsWorkspaces, undefined)
t.true(jsWorkspaces.isRoot)
t.is(jsWorkspaces.packages.length, 2)
})

test('js-workspaces: detects rootDir is the same as the projectDir and sets the isRoot flag to true', async (t) => {
const { jsWorkspaces } = await getBuildInfo({
rootDir: `${FIXTURES_ABSOLUTE_PATH}/js-workspaces`,
projectDir: `${FIXTURES_RELATIVE_PATH}/js-workspaces`,
})
t.not(jsWorkspaces, undefined)
t.true(jsWorkspaces.isRoot)
t.is(jsWorkspaces.packages.length, 2)
})

test('js-workspaces: projectDir set to workspace dir returns workspace info and isRoot flag set to false', async (t) => {
const { jsWorkspaces } = await getBuildInfo({
rootDir: `${FIXTURES_RELATIVE_PATH}/js-workspaces`,
projectDir: `${FIXTURES_RELATIVE_PATH}/js-workspaces/packages/package-1`,
})
t.not(jsWorkspaces, undefined)
t.false(jsWorkspaces.isRoot)
t.is(jsWorkspaces.packages.length, 2)
})

test('js-workspaces: if project is not part of a workspace return no workspace info', async (t) => {
const { jsWorkspaces } = await getBuildInfo({
rootDir: `${FIXTURES_RELATIVE_PATH}/js-workspaces`,
projectDir: `${FIXTURES_RELATIVE_PATH}/js-workspaces/not-in-workspace`,
})
t.is(jsWorkspaces, undefined)
})

test('js-workspaces: handles absolute paths correctly', async (t) => {
const { jsWorkspaces } = await getBuildInfo({
rootDir: `${FIXTURES_ABSOLUTE_PATH}/js-workspaces`,
projectDir: `${FIXTURES_ABSOLUTE_PATH}/js-workspaces/packages/package-1`,
})
t.not(jsWorkspaces, undefined)
t.false(jsWorkspaces.isRoot)
t.is(jsWorkspaces.packages.length, 2)
})

0 comments on commit 0dbf74b

Please sign in to comment.