Skip to content

Commit

Permalink
Merge pull request #583 from desktop/break-all-the-things
Browse files Browse the repository at this point in the history
Remove jest in favor of Node's built-in test runner
  • Loading branch information
niik authored Oct 21, 2024
2 parents b4d51b8 + c888357 commit ca11a32
Show file tree
Hide file tree
Showing 31 changed files with 842 additions and 2,602 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
fail-fast: false
matrix:
nodeVersion: [18, 20]
nodeVersion: [20]
arch: [x64]
os: [macos-latest, windows-latest, ubuntu-latest]
include:
Expand All @@ -27,7 +27,7 @@ jobs:
friendlyName: Windows
- os: windows-latest
friendlyName: Windows
nodeVersion: 18
nodeVersion: 20
arch: x86
npm_config_arch: ia32
- os: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.17.0
13 changes: 0 additions & 13 deletions jest.external.config.js

This file was deleted.

13 changes: 0 additions & 13 deletions jest.fast.config.js

This file was deleted.

13 changes: 0 additions & 13 deletions jest.slow.config.js

This file was deleted.

7 changes: 2 additions & 5 deletions lib/git-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,8 @@ export function resolveGitExecPath(
}
const gitDir = resolveGitDir(localGitDir)
if (process.platform === 'win32') {
if (process.arch === 'x64') {
return path.join(gitDir, 'mingw64', 'libexec', 'git-core')
}

return path.join(gitDir, 'mingw32', 'libexec', 'git-core')
const mingw = process.arch === 'x64' ? 'mingw64' : 'mingw32'
return path.join(gitDir, mingw, 'libexec', 'git-core')
} else {
return path.join(gitDir, 'libexec', 'git-core')
}
Expand Down
7 changes: 1 addition & 6 deletions lib/git-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,7 @@ export class GitProcess {

let result = new GitTask(
new Promise<IGitResult>(function (resolve, reject) {
let customEnv = {}
if (options && options.env) {
customEnv = options.env
}

const { env, gitLocation } = setupEnvironment(customEnv)
const { env, gitLocation } = setupEnvironment(options?.env ?? {})

// This is the saddest hack. There's a bug in the types for execFile
// (ExecFileOptionsWithBufferEncoding is the exact same as
Expand Down
24 changes: 10 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@
"build": "yarn clean && tsc -p ./tsconfig.json && tsc -p ./examples/tsconfig.json",
"prepack": "yarn build && yarn test",
"postpublish": "git push --follow-tags",
"test": "yarn test:fast && yarn test:slow && yarn test:external",
"test:fast": "cross-env LOCAL_GIT_DIRECTORY=./git/ jest --runInBand --silent --config ./jest.fast.config.js",
"test:slow": "cross-env LOCAL_GIT_DIRECTORY=./git/ jest --runInBand --silent --config ./jest.slow.config.js",
"test:external": "jest --runInBand --silent --config ./jest.external.config.js",
"test": "node script/test.mjs",
"download-git": "node ./script/download-git.js",
"postinstall": "node ./script/download-git.js",
"prettify": "prettier \"{examples,lib,script,test}/**/*.ts\" --write",
"is-it-pretty": "prettier --check \"{examples,lib,script,test}/**/*.ts\"",
"prettify": "prettier \"{examples,lib,script,test}/**/*.{ts,js,mjs}\" --write",
"is-it-pretty": "prettier \"{examples,lib,script,test}/**/*.{ts,js,mjs}\" --check",
"update-embedded-git": "node ./script/update-embedded-git.js"
},
"engines": {
"node": ">= 18"
"node": ">= 20"
},
"repository": {
"type": "git",
Expand All @@ -34,21 +31,20 @@
"homepage": "https://github.com/desktop/dugite#readme",
"dependencies": {
"progress": "^2.0.3",
"tar": "^6.1.11"
"tar": "^7.1.0"
},
"devDependencies": {
"@types/jest": "^28.1.7",
"@types/node": "18",
"@types/progress": "^2.0.1",
"@types/rimraf": "2.0.2",
"@types/tar": "^6.1.2",
"cross-env": "^5.2.0",
"@types/temp": "^0.9.4",
"find-git-exec": "^0.0.4",
"jest": "^28.1.3",
"node-test-github-reporter": "^1.2.0",
"prettier": "^3.3.1",
"rimraf": "^2.5.4",
"temp": "^0.9.0",
"ts-jest": "^28.0.8",
"rimraf": "^5.0.7",
"temp": "^0.9.4",
"tsx": "^4.10.5",
"typescript": "^5.4.5"
}
}
16 changes: 9 additions & 7 deletions script/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ function getConfig() {
source: '',
checksum: '',
fileName: '',
tempFile: ''
tempFile: '',
}

// Possible values are ‘x64’, ‘arm’, ‘arm64’, ‘s390’, ‘s390x’, ‘mipsel’, ‘ia32’, ‘mips’, ‘ppc’ and ‘ppc64’
let arch = os.arch();
let arch = os.arch()

if (process.env.npm_config_arch) {
// If a specific npm_config_arch is set, we use that one instead of the OS arch (to support cross compilation)
console.log('npm_config_arch detected: ' + process.env.npm_config_arch);
arch = process.env.npm_config_arch;
console.log('npm_config_arch detected: ' + process.env.npm_config_arch)
arch = process.env.npm_config_arch
}

if (process.platform === 'win32' && arch === 'arm64') {
// Use the Dugite Native ia32 package for Windows arm64 (arm64 can run 32-bit code through emulation)
console.log('Downloading 32-bit Dugite Native for Windows arm64');
arch = 'ia32';
console.log('Downloading 32-bit Dugite Native for Windows arm64')
arch = 'ia32'
}

const key = `${process.platform}-${arch}`
Expand All @@ -37,7 +37,9 @@ function getConfig() {
config.checksum = entry.checksum
config.source = entry.url
} else {
console.log(`No embedded Git found for ${process.platform} and architecture ${arch}`)
console.log(
`No embedded Git found for ${process.platform} and architecture ${arch}`
)
}

if (config.source !== '') {
Expand Down
187 changes: 86 additions & 101 deletions script/download-git.js
Original file line number Diff line number Diff line change
@@ -1,132 +1,117 @@
const fs = require('fs')

const ProgressBar = require('progress')
const tar = require('tar')
const https = require('https')
const { createHash } = require('crypto')
const { rm, rmSync, mkdir, createReadStream, createWriteStream, existsSync } = require('fs')
const { createReadStream, createWriteStream } = require('fs')

const { rm, mkdir, access } = require('fs/promises')

/**
* Returns a value indicating whether or not the provided path exists (as in
* whether it's visible to the current process or not).
*/
const pathExists = path =>
access(path).then(
() => true,
() => false
)

const { Readable } = require('stream')

const config = require('./config')()

const verifyFile = function(file, callback) {
const h = createHash('sha256').on('finish', () => {
const hash = h.digest('hex')
const match = hash === config.checksum
if (!match) {
console.log(`Validation failed. Expected '${config.checksum}' but got '${hash}'`)
}
callback(match)
})
const verifyFile = function (file, callback) {
return new Promise((resolve, reject) => {
const h = createHash('sha256')
.on('error', reject)
.on('finish', () => {
const hash = h.digest('hex')
if (hash !== config.checksum) {
reject(
new Error(
`Validation failed. Expected '${config.checksum}' but got '${hash}'`
)
)
} else {
resolve()
}
})

createReadStream(file).pipe(h)
createReadStream(file).pipe(h).on('error', reject)
})
}

const unpackFile = function(file) {
const unpackFile = file =>
tar.x({ cwd: config.outputPath, file }).catch(e => {
console.log('Unable to extract archive, aborting...', error)
console.log('Unable to extract archive, aborting...', e)
process.exit(1)
})
}

const downloadAndUnpack = (url, isFollowingRedirect) => {
if (!isFollowingRedirect) {
console.log(`Downloading Git from: ${url}`)
}

const options = {
const downloadAndUnpack = async url => {
const res = await fetch(url, {
headers: {
Accept: 'application/octet-stream',
'User-Agent': 'dugite'
'User-Agent': 'dugite',
},
secureProtocol: 'TLSv1_2_method'
}

const req = https.get(url, options)

req.on('error', function(error) {
if (error.code === 'ETIMEDOUT') {
console.log(
`A timeout has occurred while downloading '${url}' - check ` +
`your internet connection and try again. If you are using a proxy, ` +
`make sure that the HTTP_PROXY and HTTPS_PROXY environment variables are set.`,
error
)
} else {
console.log(`Error raised while downloading ${url}`, error)
}
}).catch(e => {
console.log('Unable to download archive, aborting...', e)
process.exit(1)
})

req.on('response', function(res) {
if ([301, 302].includes(res.statusCode) && res.headers['location']) {
downloadAndUnpack(res.headers.location, true)
return
}

if (res.statusCode !== 200) {
console.log(`Non-200 response returned from ${url} - (${res.statusCode})`)
process.exit(1)
}

const len = parseInt(res.headers['content-length'], 10)
if (!res.ok) {
console.log(`Got ${res.status} trying to download archive, aborting...`)
process.exit(1)
}

const bar = new ProgressBar('Downloading Git [:bar] :percent :etas', {
complete: '=',
incomplete: ' ',
width: 50,
total: len
})
const len = parseInt(res.headers.get('content-length'), 10)

res.pipe(createWriteStream(config.tempFile))
const bar = new ProgressBar('Downloading Git [:bar] :percent :etas', {
complete: '=',
incomplete: ' ',
width: 50,
total: len,
})

res.on('data', c => bar.tick(c.length))
res.on('end', function() {
verifyFile(config.tempFile, valid => {
if (valid) {
unpackFile(config.tempFile)
} else {
console.log(`checksum verification failed, refusing to unpack...`)
process.exit(1)
}
})
})
await new Promise((resolve, reject) => {
Readable.fromWeb(res.body)
.on('data', c => bar.tick(c.length))
.pipe(createWriteStream(config.tempFile))
.on('error', reject)
.on('finish', resolve)
})
await verifyFile(config.tempFile)
await unpackFile(config.tempFile)
}

if (config.source === '') {
console.log(
`Skipping downloading embedded Git as platform '${process.platform}' is not supported.`
)
console.log(`To learn more about using dugite with a system Git: https://git.io/vF5oj`)
process.exit(0)
}
;(async function run() {
if (config.source === '') {
console.log(
`Skipping downloading embedded Git as platform '${process.platform}' is not supported.`
)
console.log(
`To learn more about using dugite with a system Git: https://git.io/vF5oj`
)
process.exit(0)
}

rm(config.outputPath, { recursive: true, force: true }, error => {
if (error) {
await rm(config.outputPath, { recursive: true, force: true }).catch(error => {
console.log(`Unable to clean directory at ${config.outputPath}`, error)
process.exit(1)
}

mkdir(config.outputPath, { recursive: true }, function(error) {
if (error) {
console.log(`Unable to create directory at ${config.outputPath}`, error)
process.exit(1)
}
})

const tempFile = config.tempFile
await mkdir(config.outputPath, { recursive: true }).catch(error => {
console.log(`Unable to create directory at ${config.outputPath}`, error)
process.exit(1)
})

if (existsSync(tempFile)) {
verifyFile(tempFile, valid => {
if (valid) {
unpackFile(tempFile)
} else {
rmSync(tempFile)
downloadAndUnpack(config.source)
}
})
return
}
const tempFile = config.tempFile

downloadAndUnpack(config.source)
})
})
if (await pathExists(tempFile)) {
await verifyFile(tempFile).catch(e => {
console.log('Unable to verify cached archive, removing...', e)
return rm(tempFile)
})
await unpackFile(tempFile)
} else {
await downloadAndUnpack(config.source)
}
})()
Loading

0 comments on commit ca11a32

Please sign in to comment.