Skip to content
Merged
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ignore-scripts=true
57 changes: 41 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
"test:mocked": "jest --silent --runInBand --config=jest.config.js --coverage",
"lint:fix": "npx prettier --write \"{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"",
"lint": "npx prettier --check \"{src,test}/**/*.{ts,tsx,js,jsx,html,css,sass,less,yml,md,graphql}\"",
"preinstall": "npm run nodeVersionMessage",
"prepare": "git rev-parse --git-dir && git config core.hooksPath ./.git-hooks || true",
"doc": "npx compodoc -p tsconfig.doc.json --coverageTest 16 --coverageTestThresholdFail"
},
Expand Down Expand Up @@ -51,7 +50,7 @@
"access": "public"
},
"dependencies": {
"@sasjs/adapter": "^4.16.0",
"@sasjs/adapter": "^4.16.1",
"@sasjs/core": "4.59.9",
"@sasjs/lint": "2.4.3",
"@sasjs/utils": "3.5.2",
Expand Down
17 changes: 15 additions & 2 deletions src/commands/build/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,19 @@ import { getBuildInit, getBuildTerm } from './internal/config'
import { getLaunchPageCode } from './internal/getLaunchPageCode'

export async function build(target: Target) {
const { macroCorePath } = process.sasjsConstants

if (macroCorePath === '') {
throw new Error(
`The @sasjs/core folder location is unknown.\n` +
`Check that @sasjs/core is a dependency in the package.json, and \n` +
`that the package has been installed.\n` +
`Alternatively populate environment variable 'macroCorePath' with\n` +
`the path to a local @sasjs/core package's root directory.`
)
}
process.logger?.info(`@sasjs/core found at ${macroCorePath}`)

if (
process.sasjsConstants.buildDestinationFolder &&
!(await folderExists(process.sasjsConstants.buildDestinationFolder))
Expand Down Expand Up @@ -203,11 +216,11 @@ ${
* The serverName represents the SAS 9 logical server context
* There is no programmatic (SAS code) way to obtain this
* So it is taken from the sasjsconfig file OR supplied at runtime, eg:
*
*
* %let apploc=/my/apploc;
* %let serverName=SASAppDC;
* %inc thisfile;
*
*
*/

%global serverName;
Expand Down
14 changes: 13 additions & 1 deletion src/utils/setConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,19 @@ export const setConstants = async (
const buildDestinationJobsFolder = path.join(buildDestinationFolder, 'jobs')
const buildDestinationDbFolder = path.join(buildDestinationFolder, 'db')
const buildDestinationDocsFolder = path.join(buildDestinationFolder, 'docs')
const macroCorePath = await getNodeModulePath('@sasjs/core')
// Edge case: @sasjs/cli has a dependency on @sasjs/core.
// When @sasjs/cli is used to submit a test of the @sasjs/core
// repo, it is desirable to use that @sasjs/core repo as the dependency rather
// than the older version in @sasjs/cli node_modules.
// To achieve this, set environment variable `macroCorePath` to the root dir
// of the local @sasjs/core package. If found, this takes precedence over
// any node_modules installations of @sasjs/core.
let macroCorePath = (process.env.macroCorePath as string) ?? ''
if (macroCorePath === '') {
// If no environment variable is set/populated then check for an installed
// @sasjs/core in locations known to node.
macroCorePath = await getNodeModulePath('@sasjs/core')
}

const buildDestinationResultsFolder = getAbsolutePath(
buildResultsFolder,
Expand Down
82 changes: 59 additions & 23 deletions src/utils/spec/setConstants.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ import path from 'path'
import * as configUtils from '../config'
import { setConstants } from '../setConstants'
import * as fileModule from '@sasjs/utils/file'
import * as utils from '../utils'

describe('setConstants', () => {
let config: Configuration
const origProcessEnv = process.env

beforeAll(async () => {
;({ config } = JSON.parse(
await fileModule.readFile(path.join(__dirname, '..', '..', 'config.json'))
))
})

afterEach(() => {
process.env = { ...origProcessEnv }
})

test('should set constants inside appFolder when @sasjs/core dependency is present', async () => {
const appFolder = ['some', 'app', 'folder'].join(path.sep)
process.projectDir = appFolder
process.projectDir = process.cwd()

jest
.spyOn(configUtils, 'getLocalOrGlobalConfig')
Expand All @@ -26,14 +31,8 @@ describe('setConstants', () => {
})
)

jest.spyOn(process, 'cwd').mockImplementation(() => appFolder)

const hasSasjsCore = true

jest
.spyOn(fileModule, 'folderExists')
.mockImplementation((path: string) => Promise.resolve(hasSasjsCore))

await setConstants()

verifySasjsConstants(process.projectDir, hasSasjsCore)
Expand All @@ -42,6 +41,7 @@ describe('setConstants', () => {
test('should set constants inside appFolder when @sasjs/core dependency is not present', async () => {
const appFolder = ['some', 'app', 'folder'].join(path.sep)
process.projectDir = appFolder
process.env.macroCorePath = undefined

jest
.spyOn(configUtils, 'getLocalOrGlobalConfig')
Expand All @@ -54,20 +54,16 @@ describe('setConstants', () => {

jest.spyOn(process, 'cwd').mockImplementation(() => appFolder)

jest
.spyOn(fileModule, 'folderExists')
.mockImplementation((folderPath: string) =>
Promise.resolve(
folderPath !== path.join(appFolder, 'node_modules', '@sasjs', 'core')
)
)
jest.spyOn(utils, 'getNodeModulePath').mockImplementation(async () => '')

await setConstants()

verifySasjsConstants(process.projectDir)
})

test('should set constants outside appFolder', async () => {
process.env.macroCorePath = undefined

jest
.spyOn(configUtils, 'getLocalOrGlobalConfig')
.mockImplementation(async () =>
Expand All @@ -77,10 +73,48 @@ describe('setConstants', () => {
})
)

jest.spyOn(utils, 'getNodeModulePath').mockImplementation(async () => '')

await setConstants(false)

verifySasjsConstants(undefined, false, false)
})

test('should call getNodeModulePath once when environment variable macroCorePath is undefined', async () => {
process.env.macroCorePath = undefined

const getNodeModulePathSpy = jest
.spyOn(utils, 'getNodeModulePath')
.mockImplementation(async (packageName: string) => Promise.resolve(''))

await setConstants()

expect(getNodeModulePathSpy).toHaveBeenCalledOnceWith('@sasjs/core')
})

test('should call getNodeModulePath once when environment variable macroCorePath is blank', async () => {
process.env.macroCorePath = ''

const getNodeModulePathSpy = jest
.spyOn(utils, 'getNodeModulePath')
.mockImplementation(async (packageName: string) => Promise.resolve(''))

await setConstants()

expect(getNodeModulePathSpy).toHaveBeenCalledOnceWith('@sasjs/core')
})

test('should not call getNodeModulePath when environment variable macroCorePath is populated', async () => {
process.env.macroCorePath = '../core'

const getNodeModulePathSpy = jest
.spyOn(utils, 'getNodeModulePath')
.mockImplementation(async (packageName: string) => Promise.resolve(''))

await setConstants()

expect(getNodeModulePathSpy).toBeCalledTimes(0)
})
})

const verifySasjsConstants = (
Expand Down Expand Up @@ -126,15 +160,17 @@ const verifySasjsConstants = (
path.join(prefixAppFolder, isLocal ? '' : '.sasjs', 'sasjsbuild', 'tests')
)

const corePath = hasSasjsCore
? 'core'
: path.join('cli', 'node_modules', '@sasjs', 'core')
const corePath = hasSasjsCore ? 'core' : ''

if (appFolder) {
expect(sasjsConstants.macroCorePath).toEqual(
path.join(prefixAppFolder, 'node_modules', '@sasjs', corePath)
)
if (hasSasjsCore) {
if (appFolder) {
expect(sasjsConstants.macroCorePath).toEqual(
path.join(prefixAppFolder, 'node_modules', '@sasjs', corePath)
)
} else {
expect(sasjsConstants.macroCorePath).toEqual(expect.toEndWith(corePath))
}
} else {
expect(sasjsConstants.macroCorePath).toEqual(expect.toEndWith(corePath))
expect(sasjsConstants.macroCorePath).toEqual(corePath)
}
}
Loading
Loading