Skip to content
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

Test status checks when creating PR #12

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 0 additions & 26 deletions .github/auto-assign.yml

This file was deleted.

14 changes: 0 additions & 14 deletions .github/workflows/auto-assign.yml

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Back-end Tests
name: Comprehensive Test Suite
on:
schedule:
- cron: "0 16 * * *" # Daily at noon EST
Expand All @@ -20,7 +20,7 @@ permissions:

jobs:
testing:
name: Back-end tests on ${{ matrix.os }}
name: Run test suite on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
defaults:
run:
Expand Down
70 changes: 58 additions & 12 deletions packages/core/assets/electron/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import electron, { app, shell, BrowserWindow, ipcMain } from 'electron'
import { join, basename } from 'node:path'
import { join, basename, extname } from 'node:path'
import * as utils from '@electron-toolkit/utils'

import * as services from '../services/index'
import { existsSync } from 'node:fs';

function normalizeAndCompare(path1, path2, comparison = (a,b) => a === b) {
const decodePath = (path) => decodeURIComponent(path.replace(/\/+$/, '')); // Remove trailing slashes and decode
return comparison(decodePath(path1), decodePath(path2))
}

// Custom Window Flags
// __main: Is Main Window
Expand Down Expand Up @@ -224,6 +230,22 @@ const runWindowPlugins = async (win: BrowserWindow | null = null, type = 'load',

let windowCount = 0

// ------------------------ Window Page Load Behavior ------------------------
const loadPage = (win, page) => {

const location = getPageLocation(page)

try {
new URL(location)
win.loadURL(location)
}

// NOTE: Catching the alternative location results in a delay depending on load time
catch {
win.loadFile(location).catch(() => win.loadFile(getPageLocation(page, true)))
}
}

async function createWindow (page, options: WindowOptions = {}, toIgnore?: string[], isMainWindow: boolean = false) {

const copy = structuredClone({...defaultWindowConfig, ...options})
Expand Down Expand Up @@ -254,6 +276,16 @@ const runWindowPlugins = async (win: BrowserWindow | null = null, type = 'load',
const win = new BrowserWindow({ ...copy, show: false }) // Always initially hide the window
Object.assign(win, flags)

// CAtch all navigation events
win.webContents.on('will-navigate', (event, url) => {

event.preventDefault()
const urlObj = new URL(url)
const file = urlObj.pathname
loadPage(win, file)
})


Object.defineProperty(win, "__show", {
get: () => flags.__show,
set: (v) => {
Expand Down Expand Up @@ -303,28 +335,42 @@ const runWindowPlugins = async (win: BrowserWindow | null = null, type = 'load',
await runWindowPlugins(win, 'load', toIgnore)

// ------------------------ Window Page Load Behavior ------------------------
try {
new URL(page)
win.loadURL(page)
}

catch {
win.loadFile(page)
}

loadPage(win, page)
await new Promise(resolve => win.once('ready-to-show', resolve)) // Show after plugin loading

win.show() // Allow annotating to skip show

return win
}

function getPageLocation(pathname: string = 'index.html', alt = false) {

const isDevServer = utils.is.dev && devServerURL
if (isDevServer) return join(devServerURL, pathname)

const isContained = normalizeAndCompare(pathname, __dirname, (a,b) => a.startsWith(b))

// Check if dirname in the path
const location = isContained ? pathname : join(__dirname, pathname)

// Assume a file
if (extname(location)) return location // Return if file extension is present

const html = location + '.html' // Add .html extension if not present
const index = join(location, 'index.html')

if (existsSync(html)) return html // Return if .html file exists
if (existsSync(index)) return index // Return if index.html file exists

return alt ? html : index // NOTE: This is because we cannot check for existence in the .asar archive
}


async function createMainWindow() {
const windows = BrowserWindow.getAllWindows()
if (windows.find(o => o.__main)) return // Force only one main window
const pageToRender = utils.is.dev && devServerURL ? devServerURL : join(__dirname, 'index.html')
return await createWindow(pageToRender, windowOptions, [], true)

return await createWindow(undefined, windowOptions, [], true)
}

// ------------------------ App Start Behavior ------------------------
Expand Down
2 changes: 1 addition & 1 deletion packages/core/build.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Build-In Modules
import path, { dirname, isAbsolute, join, relative, resolve } from "node:path"
import { lstatSync } from "node:fs"

// General Internal Imports
import { isDesktop, getBuildConfig, globalTempDir, templateDir, ensureTargetConsistent, isMobile, globalWorkspacePath, handleTemporaryDirectories, chalk, vite, electronVersion } from "./globals.js"
import { BuildOptions, BuildHooks, WritableElectronBuilderConfig } from "./types.js"

// Internal Utilities
import { clear, buildAssets, getAssetBuildPath } from "./utils/assets.js"
import { lstatSync } from './utils/lstat.js'
import { printHeader, printTarget } from "./utils/formatting.js"
import { getIcon } from "./utils/index.js"
import merge from './utils/merge.js'
Expand Down
3 changes: 2 additions & 1 deletion packages/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Built-In Modules
import { dirname, join, relative, normalize, resolve } from 'node:path'
import { existsSync, lstatSync, unlink, writeFileSync } from 'node:fs'
import { existsSync, unlink, writeFileSync } from 'node:fs'
import { pathToFileURL } from 'node:url'

// Internal Imports
Expand All @@ -11,6 +11,7 @@ import { resolveFile, getJSON } from './utils/files.js'
import merge from './utils/merge.js'
import { bundleConfig } from './utils/assets.js'
import { printFailure, printSubtle } from './utils/formatting.js'
import { lstatSync } from './utils/lstat.js'

// Top-Level Package Exports
export * from './types.js'
Expand Down
9 changes: 7 additions & 2 deletions packages/core/utils/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,10 @@ export const getAssets = async ( resolvedConfig: ResolvedConfig, toBuild: Assets

const toCopy = output === null ? null : output ?? ( base ?? filepath )

if (!existsSync(toCopy)) console.log(`${_chalk.bold(`Missing ${_chalk.red(name)} build file`)}\nCould not find ${toCopy}`)
if (!existsSync(toCopy)) {
console.log(`${_chalk.bold(`Missing ${_chalk.red(name)} build file`)}\nCould not find ${toCopy}`)
return null // Do not try to copy or bundle the missing file
}

return toCopy

Expand Down Expand Up @@ -380,8 +383,10 @@ export const buildAssets = async (config: ResolvedConfig, toBuild: AssetsToBuild
const { input, output, compile } = resolvedInfo
const result = await compile({ src: input, out: output })

if (!result) continue // Skip if no result

// Copy results
if (result && existsSync(result)) assets.copy.push({ input: result, extraResource: true, sign: true })
else if (existsSync(result)) assets.copy.push({ input: result, extraResource: true, sign: true })

// Or attempt auto-bundle
else toBundle.push({
Expand Down
3 changes: 2 additions & 1 deletion packages/core/utils/copy.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { copyFileSync, mkdirSync, lstatSync, cpSync } from "node:fs"
import { copyFileSync, mkdirSync, cpSync } from "node:fs"
import { dirname, relative, sep } from "node:path"

import { safeJoin } from './index'
import { lstatSync } from './lstat'

export const copyAsset = (input, output) => {

Expand Down
7 changes: 7 additions & 0 deletions packages/core/utils/lstat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { lstatSync as getStats } from "node:fs"

export const lstatSync = (path) => {
if (path.length >= 260 && process.platform === 'win32') path = "\\\\?\\" + path
return getStats(path)
}

12 changes: 9 additions & 3 deletions packages/core/vite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export const resolveViteConfig = async (

const plugins: Plugin[] = [ ]

const { name, appId, root, icon, description } = commonersConfig
const { name, appId, root, icon, description, pages } = commonersConfig

// Desktop Build
if (isDesktopTarget) {
Expand All @@ -140,7 +140,12 @@ export const resolveViteConfig = async (
// @ts-ignore
plugins.push(...VitePWAPlugin({ registerType: 'autoUpdate', ...opts }))
}


// Resolve pages if they exist
const rollupOptions = pages ? { input: Object.entries(pages).reduce((acc, [name, filepath]) => {
acc[name] = join(root, filepath)
return acc
}, {}) } : {}

// Define a default set of plugins and configuration options
const viteConfig = _vite.defineConfig({
Expand All @@ -149,7 +154,8 @@ export const resolveViteConfig = async (
root, // Resolve index.html from the root directory
build: {
emptyOutDir: false,
outDir
outDir,
rollupOptions
},
plugins,
server: { open: !isDesktopTarget && !process.env.VITEST }, // Open the browser unless testing / building for desktop
Expand Down
77 changes: 42 additions & 35 deletions packages/core/vite/plugins/commoners.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

import { extname, resolve } from 'node:path'
import { extname, resolve, dirname, join } from 'node:path'
import { getIcon } from '../../utils/index.js'
import { isDesktop, isMobile } from '../../globals.js'

Expand Down Expand Up @@ -60,39 +60,6 @@ export default ({
const desktop = isDesktop(target)
const mobile = isMobile(target)

const configRoot = config.root
const root = _assetOutDir ? actualOutDir : configRoot
const relTo = build ? assetOutDir : root

const updatedConfigURL = getAssetLinkPath('commoners.config.mjs', assetOutDir, relTo)

const services = sanitize(config.services)

const rawIconSrc = getIcon(config.icon)
const resolvedIcon = rawIconSrc ? resolve(configRoot, rawIconSrc) : null
const iconPath = resolvedIcon ? getAssetLinkPath(resolvedIcon, assetOutDir, relTo) : null

const globalObject = {

NAME: config.name,
VERSION: config.version,
ICON: iconPath,
SERVICES: services,

// Target Shortcuts
DESKTOP: desktop,
MOBILE: mobile,
WEB: !desktop && !mobile,

// Production vs Development
DEV: dev,
PROD: !dev,

ENV: env
}

const faviconLink = rawIconSrc ? `<link rel="shortcut icon" href="${iconPath}" type="image/${extname(iconPath).slice(1)}" >` : ''

const resolvedVirtualModuleId = '\0' + virtualModuleId

return {
Expand All @@ -110,8 +77,48 @@ export default ({
return lines.join("\n")
}
},
transformIndexHtml(html) {
transformIndexHtml(html, ctx) {

const { path: htmlPath } = ctx

const parent = dirname(htmlPath)

// Resolve paths per HTML file built
const configRoot = config.root

const root = _assetOutDir ? actualOutDir : configRoot
const relTo = join(build ? assetOutDir : root, parent) // Resolve actual path in the assets

const updatedConfigURL = getAssetLinkPath('commoners.config.mjs', assetOutDir, relTo)

const services = sanitize(config.services)

const rawIconSrc = getIcon(config.icon)
const resolvedIcon = rawIconSrc ? resolve(configRoot, rawIconSrc) : null
const iconPath = resolvedIcon ? getAssetLinkPath(resolvedIcon, assetOutDir, relTo) : null

const globalObject = {

NAME: config.name,
VERSION: config.version,
ICON: iconPath,
SERVICES: services,

// Target Shortcuts
DESKTOP: desktop,
MOBILE: mobile,
WEB: !desktop && !mobile,

// Production vs Development
DEV: dev,
PROD: !dev,

ENV: env
}

const faviconLink = rawIconSrc ? `<link rel="shortcut icon" href="${iconPath}" type="image/${extname(iconPath).slice(1)}" >` : ''

// Inject required items into the HTML head
const headStart = html.indexOf(TAGS.head.start)
const headEnd = html.indexOf(TAGS.head.end)
const headContent = headStart && headEnd ? html.slice(headStart + TAGS.head.start.length, headEnd) : ''
Expand Down
5 changes: 5 additions & 0 deletions tests/demo/commoners.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ const TEST_OPTIONS = {
const config = {

name,

pages: {
main: './index.html',
nested: './pages/nested.html'
},

plugins: {
checks: checksPlugin,
Expand Down
Loading
Loading