Skip to content

Commit

Permalink
fix(app-config): Load app id from appinfo if possible
Browse files Browse the repository at this point in the history
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
  • Loading branch information
susnux committed Jun 20, 2024
1 parent eb4410c commit f8357a5
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 6 deletions.
33 changes: 27 additions & 6 deletions lib/appConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,23 @@
import type { Plugin, UserConfig, UserConfigFn } from 'vite'
import type { BaseOptions, NodePolyfillsOptions } from './baseConfig.js'

import { readFileSync } from 'node:fs'
import { relative } from 'node:path'
import { cwd } from 'node:process'
import { mergeConfig } from 'vite'
import { createBaseConfig } from './baseConfig.js'
import { findAppinfo } from './utils/appinfo.js'

import EmptyJSDirPlugin from './plugins/EmptyJSDir.js'
import replace from '@rollup/plugin-replace'
import injectCSSPlugin from 'vite-plugin-css-injected-by-js'

type VitePluginInjectCSSOptions = Parameters<typeof injectCSSPlugin>[0]

export const appVersion = process.env.npm_package_version
export const sanitizeAppName = (appName: string) => appName.replace(/[/\\]/, '-')

export interface AppOptions extends Omit<BaseOptions, 'inlineCSS'> {
/**
* Override the `appName`, by default the name from the `package.json` is used.
* Override the `appName`, by default the name from the `appinfo/info.xml` and if not found the name from `package.json` is used.
* But if that name differs from the app id used for the Nextcloud app you need to override it.
* @default process.env.npm_package_name
*/
appName?: string

Expand Down Expand Up @@ -78,7 +77,6 @@ export interface AppOptions extends Omit<BaseOptions, 'inlineCSS'> {
export const createAppConfig = (entries: { [entryAlias: string]: string }, options: AppOptions = {}): UserConfigFn => {
// Add default options
options = {
appName: process.env.npm_package_name,
config: {},
nodePolyfills: {
protocolImports: true,
Expand All @@ -87,6 +85,29 @@ export const createAppConfig = (entries: { [entryAlias: string]: string }, optio
...options,
}

let appVersion: string

const appinfo = findAppinfo(cwd())
if (appinfo) {
const content = String(readFileSync(appinfo))
const version = content.match(/<version>([^<]+)<\/version>/i)[1]
const id = content.match(/<id>([^<]+)<\/id>/i)[1]

if (version) {
appVersion = version
}
if (id && !options.appName) {
options.appName = id
}
} else {
appVersion = process.env.npm_package_version
}

if (!options.appName) {
console.warn('No app name configured, falling back to name from `package.json`')
options.appName = process.env.npm_package_name
}

return createBaseConfig({
...(options as BaseOptions),
config: async (env) => {
Expand Down
46 changes: 46 additions & 0 deletions lib/utils/appinfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { lstatSync } from 'node:fs'
import { join, resolve, sep } from 'node:path'

/**
* Check if a given path exists and is a directory
*
* @param {string} filePath The path
* @return {boolean}
*/
function isDirectory(filePath: string): boolean {
const stats = lstatSync(filePath, { throwIfNoEntry: false })
return stats !== undefined && stats.isDirectory()
}

/**
* Check if a given path exists and is a directory
*
* @param {string} filePath The path
* @return {boolean}
*/
function isFile(filePath: string): boolean {
const stats = lstatSync(filePath, { throwIfNoEntry: false })
return stats !== undefined && stats.isFile()
}

/**
* Find the path of nearest `appinfo/info.xml` relative to given path
*
* @param {string} currentPath The path to check for appinfo
* @return {string|undefined} Either the full path including the `info.xml` part or `undefined` if no found
*/
export function findAppinfo(currentPath: string): string | null {
while (currentPath && currentPath !== sep) {
const appinfoPath = join(currentPath, 'appinfo')
if (isDirectory(appinfoPath) && isFile(join(appinfoPath, 'info.xml'))) {
return join(appinfoPath, 'info.xml')
}
currentPath = resolve(currentPath, '..')
}
return undefined
}

0 comments on commit f8357a5

Please sign in to comment.