Skip to content

Commit

Permalink
Windows compatibility (HoudiniGraphql#612)
Browse files Browse the repository at this point in the history
* create path package

* centralize import path logic

* comments

* remove os from runtime

* add windows e2e test to workflow

* add runs-on back

* missing strategy key?

* no need for ubuntu AND osx

* add logs

* some logs

* so it begins

* who cares

* a

* log dir contents

* b

* c

* d

* e

* mkdir before build

* glob needs unix paths

* use os for playwright cache key

* pnpm cache use matrix

* remove ci caching

* pnpm playwright

* @playwright/test as top level dep

* add cache back

* changeset

* copy over changes

* add playwright cache check back

* move glob to local fs

* remove unused imports

* remove unused imports

* use default glob export

* fix glob import in typedefs

* remove playwright cache

* more unused imports

* fix sponsor link
  • Loading branch information
AlecAivazis authored and endigma committed Nov 10, 2024
1 parent 83bc94a commit e3870f4
Show file tree
Hide file tree
Showing 52 changed files with 198 additions and 182 deletions.
5 changes: 5 additions & 0 deletions .changeset/quick-toys-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'houdini': patch
---

Fix windows compatability
2 changes: 2 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ module.exports = {
'no-var': 'off',
'no-undef': 'off',
'object-shorthand': 'off',
'unused-imports/no-unused-imports': 'error',
// 'no-console': ['error', { allow: ['info', 'warn', 'error', 'time', 'timeEnd'] }],
},
ignorePatterns: ['e2e', 'example', 'site'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
},
plugins: ['unused-imports'],
}
23 changes: 8 additions & 15 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ jobs:

e2e_sveltekit:
name: End-to-End Tests
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}

steps:
- name: Checkout source
Expand Down Expand Up @@ -116,9 +119,9 @@ jobs:
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
key: ${{ matrix.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
${{ matrix.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install
Expand All @@ -129,26 +132,16 @@ jobs:
with:
path: |
~/.cache/ms-playwright
key: cache-playwright-linux-1.25.0
key: cache-playwright-${{ matrix.os }}-1.25.0

- name: Build packages
run: pnpm run compile

- name: Install Playwright
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps
run: pnpm playwright install --with-deps

- name: End-to-End Tests sveltekit
run: pnpm run --filter sveltekit build && pnpm --filter sveltekit tests
env:
RECORD_REPLAY_TEST_RUN_ID: ${{ env.GITHUB_SHA }}

- name: Upload videos
uses: replayio/[email protected]
if: ${{ always() }}
with:
api-key: ${{ secrets.RECORD_REPLAY_API_KEY }}
filter: ${{ 'function($v) { $v.metadata.test.result = "failed" and $v.status = "onDisk" }' }}

e2e_sveltekit_linter:
name: End-to-End Linter
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
"@changesets/changelog-git": "^0.1.13",
"@changesets/changelog-github": "^0.4.7",
"@changesets/cli": "^2.25.0",
"@playwright/test": "1.25.0",
"@theguild/eslint-config": "^0.1.0",
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
"eslint-plugin-unused-imports": "^2.0.0",
"graphql": "*",
"prettier": "^2.5.1",
"turbo": "^1.5.4",
Expand Down
6 changes: 4 additions & 2 deletions packages/_scripts/build.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import esbuild from 'esbuild'
import { replace } from 'esbuild-plugin-replace'
import fs from 'fs/promises'
import glob from 'glob-promise'
import glob from 'glob'
import path from 'path'
import { promisify } from 'util'

// the relevant directories
const build_dir = path.join(process.cwd(), 'build')
Expand Down Expand Up @@ -85,7 +86,7 @@ async function build({ package_json, source, bundle = true, plugin }) {
// if we aren't bundling, look up the entrypoints once
const children = bundle
? []
: await glob(path.join(source, '**/**/*'), {
: await promisify(glob)(path.join(source, '**/**/*').replaceAll('\\', '/'), {
nodir: true,
})

Expand Down Expand Up @@ -140,6 +141,7 @@ async function build({ package_json, source, bundle = true, plugin }) {
'utf-8'
)
} catch (e) {
console.log(e)
process.exit(1)
}
})
Expand Down
1 change: 0 additions & 1 deletion packages/_scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"esbuild-plugin-alias": "^0.2.1",
"esbuild-plugin-replace": "^1.2.0",
"glob": "^8.0.3",
"glob-promise": "^5.0.0",
"rollup": "^2.79.1",
"rollup-plugin-typescript2": "^0.34.0",
"typescript": "^4.8.4"
Expand Down
5 changes: 3 additions & 2 deletions packages/_scripts/typedefs.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import fsSync from 'fs'
import fs_extra from 'fs-extra'
import fs from 'fs/promises'
import glob from 'glob-promise'
import glob from 'glob'
import path from 'path'
import ts from 'typescript'
import { promisify } from 'util'

const { ModuleResolutionKind } = ts
const tsConfig = JSON.parse(fsSync.readFileSync('../../tsconfig.json', 'utf-8'))
Expand All @@ -15,7 +16,7 @@ export default async function generate_typedefs({ plugin }) {
)

// grab any non-tests file
const files = (await glob('./src/**/*.ts', { nodir: true })).filter(
const files = (await promisify(glob)('./src/**/*.ts', { nodir: true })).filter(
(path) => !path.endsWith('.test.ts')
)

Expand Down
3 changes: 1 addition & 2 deletions packages/houdini-svelte/src/plugin/codegen/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { fs } from 'houdini'
import path from 'path'
import { fs, path } from 'houdini'

import { PluginGenerateInput } from '.'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
import { ArtifactKind, Config, fs, GenerateHookInput } from 'houdini'
import path from 'path'
import * as recast from 'recast'
import { ArtifactKind, Config, fs, GenerateHookInput, path } from 'houdini'

import { parseSvelte } from '../../extract'
import { Framework } from '../../kit'

type ExportNamedDeclaration = recast.types.namedTypes.ExportNamedDeclaration
type VariableDeclaration = recast.types.namedTypes.VariableDeclaration

export default async function componentTypesGenerator(
framework: Framework,
{ config, documents }: GenerateHookInput
Expand Down
8 changes: 2 additions & 6 deletions packages/houdini-svelte/src/plugin/codegen/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { OperationDefinitionNode } from 'graphql'
import { Config, fs, GenerateHookInput } from 'houdini'
import path from 'path'
import { Config, fs, GenerateHookInput, path } from 'houdini'

import { extract_load_function } from '../../extractLoadFunction'
import {
Expand Down Expand Up @@ -75,10 +74,7 @@ export default async function svelteKitGenerator(
const target = path.join(type_route_dir(config), relativePath, config.typeRootFile)

// we can't import from $houdini so we need to compute the relative path from the import
const houdiniRelative = path
.relative(target, config.typeRootDir)
// Windows management
.replaceAll('\\', '/')
const houdiniRelative = path.relative(target, config.typeRootDir)

// the unique set of query names
const queryNames: string[] = []
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { parseJS, fs } from 'houdini'
import { parseJS, fs, path } from 'houdini'
import { testConfig } from 'houdini/test'
import path from 'path'
import { test, expect } from 'vitest'

import generate from '..'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { CollectedGraphQLDocument, Config, fs, GenerateHookInput } from 'houdini'
import path from 'path'
import { CollectedGraphQLDocument, fs, GenerateHookInput, path } from 'houdini'

import { global_store_name, stores_directory, store_name } from '../../kit'

Expand Down
3 changes: 1 addition & 2 deletions packages/houdini-svelte/src/plugin/codegen/stores/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { cleanupFiles, fs, ArtifactKind, GenerateHookInput } from 'houdini'
import path from 'path'
import { cleanupFiles, fs, ArtifactKind, GenerateHookInput, path } from 'houdini'

import { stores_directory } from '../../kit'
import { generateFragmentStore } from './fragment'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { CollectedGraphQLDocument, fs, GenerateHookInput } from 'houdini'
import path from 'path'
import { CollectedGraphQLDocument, fs, path, GenerateHookInput } from 'houdini'

import { global_store_name, stores_directory, store_name } from '../../kit'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { fs, CollectedGraphQLDocument } from 'houdini'
import { fs, CollectedGraphQLDocument, path } from 'houdini'
import { mockCollectedDoc } from 'houdini/test'
import path from 'path'
import * as recast from 'recast'
import * as typeScriptParser from 'recast/parsers/typescript'
import { test, expect } from 'vitest'
Expand Down
3 changes: 1 addition & 2 deletions packages/houdini-svelte/src/plugin/codegen/stores/query.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as graphql from 'graphql'
import { CollectedGraphQLDocument, GenerateHookInput } from 'houdini'
import { CollectedGraphQLDocument, GenerateHookInput, path } from 'houdini'
import { operation_requires_variables, fs } from 'houdini'
import path from 'path'

import { global_store_name, stores_directory, store_name } from '../../kit'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { CollectedGraphQLDocument, fs, GenerateHookInput } from 'houdini'
import path from 'path'
import { CollectedGraphQLDocument, fs, GenerateHookInput, path } from 'houdini'

import { global_store_name, stores_directory, store_name } from '../../kit'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { fs } from 'houdini'
import path from 'path'
import { fs, path } from 'houdini'
import { test, describe, expect } from 'vitest'

import { test_config } from '../test'
Expand Down
9 changes: 6 additions & 3 deletions packages/houdini-svelte/src/plugin/extractLoadFunction.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { ExpressionKind } from 'ast-types/gen/kinds'
import * as graphql from 'graphql'
import { Config, fs, parseJS } from 'houdini'
import path from 'path'
import { Config, fs, parseJS, path } from 'houdini'
import * as recast from 'recast'
import { transformWithEsbuild } from 'vite'

Expand Down Expand Up @@ -107,7 +106,11 @@ async function processScript(
// compute the artifact path
const artifact =
mockArtifacts?.[query] ||
(await import(path.join(config.artifactDirectory, query + '.js'))).default
(
await import(
path.importPath(path.join(config.artifactDirectory, query + '.js'))
)
).default

// save the query
globalImports[name] = artifact.raw
Expand Down
24 changes: 17 additions & 7 deletions packages/houdini-svelte/src/plugin/fsPatch.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import filesystem, { Dirent, PathLike } from 'fs'
import { fs, Plugin } from 'houdini'
import path from 'path'
import { fs, Plugin, path } from 'houdini'

import {
Framework,
Expand All @@ -14,6 +13,9 @@ import {
export default (getFramwork: () => Framework) =>
({
resolveId(filepath, _, { config }) {
// everything internal to houdini should assume posix paths
filepath = path.posixify(filepath.toString())

// if we are resolving any of the files we need to generate
if (
is_route_script(getFramwork(), filepath) ||
Expand All @@ -29,6 +31,9 @@ export default (getFramwork: () => Framework) =>
},

load: async (filepath, { config }) => {
// everything internal to houdini should assume posix paths
filepath = path.posixify(filepath.toString())

// if we are processing a route script or the root layout, we should always return _something_
if (
is_route_script(getFramwork(), filepath) ||
Expand Down Expand Up @@ -101,13 +106,16 @@ filesystem.statSync = function (filepath: string, options: Parameters<filesystem
const result = _statSync(filepath, options)
return result
} catch (error) {
// everything internal to houdini should assume posix paths
filepath = path.posixify(filepath.toString())

const mock = virtual_file(path.basename(filepath), { withFileTypes: true })

// always fake the root +layout.server.js and +layout.svelte
if (
filepath.endsWith('routes/+layout.svelte') ||
filepath.endsWith(path.join('routes', '+layout.svelte')) ||
filepath.endsWith('routes/+layout.server.js') ||
filepath.endsWith(path.join('routes', '+layout.svelte')) ||
filepath.endsWith(path.join('routes', '+layout.server.js')) ||
filepath.endsWith(path.join('routes', '+layout.server.js'))
) {
return mock
Expand Down Expand Up @@ -176,19 +184,21 @@ filesystem.readdirSync = function (
result.push(virtual_file('+layout.js', options))
}

const posix_filepath = path.posixify(filepath.toString())

// if we are in looking inside of src/routes and there's no +layout.svelte file
// we need to create one
if (is_root_route(filepath) && !contains('+layout.svelte')) {
if (is_root_route(posix_filepath) && !contains('+layout.svelte')) {
result.push(virtual_file('+layout.svelte', options))
}
// if we are in looking inside of src/routes and there's no +layout.server.js file
// we need to create one
if (is_root_route(filepath) && !contains('+layout.server.js', '+layout.server.ts')) {
if (is_root_route(posix_filepath) && !contains('+layout.server.js', '+layout.server.ts')) {
result.push(virtual_file('+layout.server.js', options))
}

// there needs to always be a root load function that passes the session down
if (is_root_route(filepath) && !contains('+layout.js', '+layout.ts')) {
if (is_root_route(posix_filepath) && !contains('+layout.js', '+layout.ts')) {
result.push(virtual_file('+layout.js', options))
}

Expand Down
14 changes: 5 additions & 9 deletions packages/houdini-svelte/src/plugin/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { HoudiniError, PluginFactory } from 'houdini'
import path from 'path'
import { HoudiniError, PluginFactory, path } from 'houdini'

import generate from './codegen'
import extract from './extract'
Expand Down Expand Up @@ -32,13 +31,10 @@ const HoudiniSveltePlugin: PluginFactory = async () => ({
'network.js'
)
// the relative path
const relativePath = path
.relative(
path.dirname(networkFilePath),
path.join(config.projectRoot, plugin_config(config).client)
)
// Windows management
.replaceAll('\\', '/')
const relativePath = path.relative(
path.dirname(networkFilePath),
path.join(config.projectRoot, plugin_config(config).client)
)

return content.replace('HOUDINI_CLIENT_PATH', relativePath)
},
Expand Down
7 changes: 2 additions & 5 deletions packages/houdini-svelte/src/plugin/kit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as graphql from 'graphql'
import { fs, find_graphql, Config } from 'houdini'
import { fs, find_graphql, Config, path } from 'houdini'
import { ensure_imports } from 'houdini/vite'
import path from 'path'
import recast from 'recast'

import { HoudiniVitePluginConfig } from '.'
Expand All @@ -18,7 +17,7 @@ export function is_route(config: Config, framework: Framework, filepath: string)
}

// only consider filepaths in src/routes
if (!posixify(filepath).startsWith(posixify(config.routesDir))) {
if (!filepath.startsWith(config.routesDir)) {
return false
}

Expand Down Expand Up @@ -313,8 +312,6 @@ const routeQueryError = (filepath: string) => ({
message: 'route query error',
})

const posixify = (str: string) => str.replace(/\\/g, '/')

export function route_page_path(config: Config, filename: string) {
return resolve_relative(config, filename).replace('.js', '.svelte').replace('.ts', '.svelte')
}
Expand Down
2 changes: 1 addition & 1 deletion packages/houdini-svelte/src/runtime/stores/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { get, Readable, Writable, writable } from 'svelte/store'

import { clientStarted, isBrowser, error } from '../adapter'
import { getCurrentClient } from '../network'
import { getClientSession, getSession } from '../session'
import { getSession } from '../session'
import { BaseStore } from './store'

export class QueryStore<
Expand Down
Loading

0 comments on commit e3870f4

Please sign in to comment.