-
Notifications
You must be signed in to change notification settings - Fork 339
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use absolute directory paths everywhere #2962
Conversation
8fe3cd0
to
67a6e4f
Compare
Related code review comments that this PR helps address: #2851 (review) from @36degrees
#2946 (comment) from @romaricpascal
|
*/ | ||
gulp.task('copy:assets', () => { | ||
return gulp.src(`${configPaths.src}assets/**/*`) | ||
return gulp.src(slash(join(configPaths.assets, '**/*'))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See commit 6e72471 regarding Gulp using its own glob library:
Note: Gulp globs use
slash()
to ensure Windows paths are flipped back to POSIX for compatibility
I did consider require('path/posix').normalize
to flip Windows backslashes back to POSIX forward slashes but we'll continue to use slash()
for this instead
@@ -93,7 +93,7 @@ module.exports = async (options) => { | |||
app.use('/vendor/govuk_frontend_toolkit/', express.static('node_modules/govuk_frontend_toolkit/javascripts/govuk/')) | |||
app.use('/vendor/jquery/', express.static('node_modules/jquery/dist')) | |||
|
|||
app.use('/assets', express.static(join(configPaths.src, 'assets'))) | |||
app.use('/assets', express.static(configPaths.assets)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We used it enough times to add a new configPaths.assets
@@ -28,7 +27,7 @@ const cache = global.cache || {} | |||
const getListing = async (directoryPath, pattern = '**/*', options = {}) => { | |||
const listing = await glob(pattern, { | |||
allowEmpty: true, | |||
cwd: join(cwd(), directoryPath), | |||
cwd: directoryPath, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We run our tooling from the project root so cwd()
has been (mostly) stable for us
But since Node.js via node
/nodemon
can launch from any directory it's better that we use absolute paths instead like we do here
@@ -39,7 +39,7 @@ describe('The settings layer', () => { | |||
|
|||
describe('Sass documentation', () => { | |||
it('associates everything with a "settings" group', async () => { | |||
const docs = await sassdoc.parse(join(configPaths.src, 'settings', '*.scss')) | |||
const docs = await sassdoc.parse(join(configPaths.src, 'govuk/settings/**/*.scss')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll still see us using /
forward slashes within join()
as @romaricpascal pointed out that normalize()
is also run behind the scenes 🙌
https://nodejs.org/api/path.html#pathjoinpaths
The
path.join()
method joins all given path segments together using the platform-specific separator as a delimiter, then normalizes the resulting path.
|
||
const { destination } = require('./task-arguments.js') | ||
const cleanPath = slash(destination) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to Gulp's glob-parent
not supporting Windows paths we know our "clean" task's del@6.1.1
package uses globby
which also wants POSIX forward slashes 😭
@@ -105,10 +105,10 @@ gulp.task('js:compile', async () => { | |||
|
|||
// This is combined with destPath in gulp.dest() | |||
// so the files are output to the correct folders | |||
const modulePath = slash(srcPath).replace(/^govuk/, '') | |||
const modulePath = slash(srcPath).replace(/^govuk\/?/, '') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tiny future bug fix here as we missed govuk/
→ /
trailing slashes
`${configPaths.fullPageExamples}**/*.scss`, | ||
`!${configPaths.src}vendor/*` | ||
`${slash(configPaths.src)}/govuk/**/**/*.scss`, | ||
`${slash(configPaths.app)}/assets/scss/**/*.scss`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caught me out at first as this is different to configPaths.assets
@@ -23,13 +23,13 @@ const destination = argv.destination || (destinations | |||
.filter(({ task }) => tasks.includes(task))[0]?.destination ?? 'public') | |||
|
|||
const rootPath = dirname(__dirname) | |||
const destPath = resolve(rootPath, destination) | |||
const destPath = resolve(rootPath, slash(destination)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the --destination
flag we have tests for both forward slashes and backslashes
We're using slash()
to remove Windows escaped paths \\
then resolve()
to normalise to the platform default—Windows paths for Windows, POSIX paths for macOS/Linux
https://nodejs.org/api/path.html#pathresolvepaths
The resulting path is normalized and trailing slashes are removed unless the path is resolved to the root directory.
// Normalise slashes (Windows) for gulp.src | ||
destination: slash(relative(rootPath, destPath)), | ||
// Absolute path to destination | ||
destination: destPath, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We no longer return 'package'
, 'public'
, 'dist'
but full absolute paths:
/path/to/project/govuk-frontend/package
/path/to/project/govuk-frontend/public
/path/to/project/govuk-frontend/dist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks so much tidier 😍 Thanks for the tedious update across the project 🙌🏻
Ran the build on Windows and it was OK. Tests had 4 failures around the shapes of the slashes in the Clean task, though 😢 :
Summary of all failing tests
FAIL tasks/clean.unit.test.js
● Clean task › cleans destination "public"
expect(received).toEqual(expected) // deep equality
- Expected - 1
+ Received + 1
Array [
- "public/**/*",
+ "public\\**\\*",
]
32 | jest.mock('./task-arguments.js', () => ({ destination: mockDestination }))
33 | const clean = await import('./clean.js')
> 34 | expect(clean.paths()).toEqual(paths)
| ^
35 | })
36 | })
37 |
at toEqual (tasks/clean.unit.test.js:34:27)
● Clean task › cleans destination "package"
expect(received).toEqual(expected) // deep equality
- Expected - 1
+ Received + 1
Array [
- "package/**/*",
+ "package\\**\\*",
"!package/",
"!package/package.json",
"!package/govuk-prototype-kit.config.json",
"!package/README.md",
]
32 | jest.mock('./task-arguments.js', () => ({ destination: mockDestination }))
33 | const clean = await import('./clean.js')
> 34 | expect(clean.paths()).toEqual(paths)
| ^
35 | })
36 | })
37 |
at toEqual (tasks/clean.unit.test.js:34:27)
● Clean task › cleans destination "dist"
expect(received).toEqual(expected) // deep equality
- Expected - 1
+ Received + 1
Array [
- "dist/**/*",
+ "dist\\**\\*",
]
32 | jest.mock('./task-arguments.js', () => ({ destination: mockDestination }))
33 | const clean = await import('./clean.js')
> 34 | expect(clean.paths()).toEqual(paths)
| ^
35 | })
36 | })
37 |
at toEqual (tasks/clean.unit.test.js:34:27)
● Clean task › cleans destination "custom/location/here"
expect(received).toEqual(expected) // deep equality
- Expected - 1
+ Received + 1
Array [
- "custom/location/here/**/*",
+ "custom\\location\\here\\**\\*",
]
32 | jest.mock('./task-arguments.js', () => ({ destination: mockDestination }))
33 | const clean = await import('./clean.js')
> 34 | expect(clean.paths()).toEqual(paths)
| ^
35 | })
36 | })
37 |
at toEqual (tasks/clean.unit.test.js:34:27)
Test Suites: 1 failed, 78 passed, 79 total
Tests: 4 failed, 1421 passed, 1425 total
Snapshots: 33 passed, 33 total
Time: 220.556 s, estimated 231 s
Ran all test suites in 4 projects.
I think the issue is with the join
on line 9 that turns back the path into a Windows path. As we're looking to create a glob, we can probably just use a template string.
Happy to run the tests again or pair to help fix it 😄
Ahh this is brilliant, thank you for being so thorough I'll probably call Reminds me I should rebase #2945 with this branch as it will have caught this. Thanks @romaricpascal |
Unused since a940adc
Ensure absolute paths are used throughout
67a6e4f
to
b4f4e3c
Compare
This PR addresses a few code review comments that have come up recently
Where are my files?
Having to use the variable
process.cwd()
to find where the project rootWhere is the src directory?
We suffix "govuk" into
configPaths.src
but (can) forget to join it to destination pathsWhere is the actual src directory?
Remembering to add
../
to remove the "govuk" suffixThis PR makes all our config paths absolute and removes the "govuk" suffix by default
Config paths
We currently used relative paths with trailing slashes
Before
Relative ish file paths
After (macOS, Linux)
Absolute file paths
After (Windows)
Absolute file paths