feat(cli) [WIP] (#34)

* feat(cli) init tauri mode

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* feat(cli:init) add force & logging flags, full JSDoc

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* feat(cli:init) remove console.log

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* feat(cli:dev) get rust compile to finish

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* feat(cli:build) get rust compile to finish

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* feat(cli) set template with current working defaults

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* chore(version) bump

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* fix(typo)

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* fix(template): missing name warning

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* fix(bundler): correct repository link

Signed-off-by: Daniel Thompson-Yvetot <denjell@quasar.dev>

* feat(lib|cli) read config from tauriDir

* chore(cli) remove console.log statement

* fix(embedded-server) JS content type

* feat(template): add rust2018 flag

* feat(cli): cleanup
This commit is contained in:
nothingismagick 2019-10-07 20:36:56 +02:00 committed by GitHub
parent d18a0e43ac
commit b93bded180
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 207 additions and 127 deletions

4
.gitignore vendored
View File

@ -59,7 +59,3 @@ typings/
debug.log
package-lock.json
.vscode/settings.json
# Quasar output
bundle.json
config.json

View File

@ -6,8 +6,3 @@ node_modules
.github
.idea
SECURITY.md
# Quasar output
quasar
bundle.json
config.json

View File

@ -1,10 +1,10 @@
[package]
name = "tauri-ui"
version = "1.0.0"
authors = ["Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot <denjell@quasar.dev>"]
authors = ["Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot"]
readme = "README.md"
license = "MIT"
repository = "https://github.com/quasarframework/tauri"
repository = "https://github.com/tauri-apps/tauri"
description = "Rust bindings for tauri, a toolchain for building more secure native apps that have tiny binaries and are very fast."
keywords = ["quasar", "web", "gui", "desktop", "webkit"]
categories = ["quasar", "gui", "web-programming", "api-bindings", "rendering", "visualization"]

View File

@ -1,9 +1,9 @@
[package]
name = "tauri-sys"
version = "1.0.0"
authors = ["Boscop", "Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot <denjell@quasar.dev>"]
authors = ["Boscop", "Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot"]
license = "MIT"
repository = "https://github.com/quasarframework/tauri"
repository = "https://github.com/tauri-apps/tauri"
description = "Rust native ffi bindings for tauri UI"
keywords = ["quasar", "web", "gui", "desktop", "webkit"]
categories = ["quasar", "gui", "web-programming", "api-bindings", "rendering", "visualization"]

View File

@ -1,7 +1,7 @@
[package]
name = "tauri"
version = "1.0.0"
authors = ["Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot <denjell@quasar.dev>"]
authors = ["Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot"]
license = "MIT"
edition = "2018"

View File

@ -24,7 +24,7 @@ fn default_resizable() -> bool {
}
fn default_title() -> String {
"Quasar Tauri App".to_string()
"Tauri App".to_string()
}
fn default_window() -> WindowConfig {
@ -70,5 +70,5 @@ pub struct Config {
}
pub fn get() -> Config {
serde_json::from_str(include_str!("../../../config.json")).unwrap()
serde_json::from_str(include_str!(concat!(env!("TAURI_CONFIG_DIR"), "/config.json"))).unwrap()
}

View File

@ -16,6 +16,8 @@ pub fn asset_response(path: &str) -> Response<std::io::Cursor<Vec<u8>>> {
header = Header::from_bytes(&b"Content-Type"[..], &b"text/css"[..]).unwrap();
} else if path.ends_with(".html") {
header = Header::from_bytes(&b"Content-Type"[..], &b"text/html"[..]).unwrap();
} else if path.ends_with(".js") {
header = Header::from_bytes(&b"Content-Type"[..], &b"text/javascript"[..]).unwrap();
} else {
header = Header::from_bytes(&b"Content-Type"[..], &b"application/octet-stream"[..]).unwrap();
}

View File

@ -1,5 +1,6 @@
/* eslint-disable */
/**
* THIS FILE IS GENERATED AUTOMATICALLY.
* * THIS FILE IS GENERATED AUTOMATICALLY.
* DO NOT EDIT.
*
* Please whitelist these API functions in <% confName %>
@ -108,7 +109,7 @@ export default class Tauri {
static emit(evt, payload) {
this.invoke({
cmd: 'emit',
evt,
event: evt,
payload
})
}

View File

@ -1,7 +1,5 @@
const
parseArgs = require('minimist'),
{ writeFileSync } = require('fs-extra'),
path = require('path')
parseArgs = require('minimist')
const argv = parseArgs(process.argv.slice(2), {
alias: {
@ -23,17 +21,16 @@ if (argv.help) {
process.exit(0)
}
const appPaths = require('../helpers/app-paths'),
const { tauriDir } = require('../helpers/app-paths'),
Runner = require('../runner'),
tauri = new Runner(appPaths),
tauri = new Runner({modeDir: tauriDir}),
tauriConfig = require('../helpers/tauri-config')({
ctx: {
debug: argv.debug
}
})
require('../generator').generate(tauriConfig.tauri)
require('../entry').generate(appPaths.tauriDir, tauriConfig, true)
require('../helpers/generator')(tauriConfig)
require('../generator').generate(tauriConfig.tauri)
require('../entry').generate(tauriDir, tauriConfig)
tauri.build(tauriConfig)

View File

@ -1,7 +1,5 @@
const
parseArgs = require('minimist'),
path = require('path'),
{ writeFileSync } = require('fs-extra')
parseArgs = require('minimist')
const argv = parseArgs(process.argv.slice(2), {
alias: {
@ -22,19 +20,16 @@ if (argv.help) {
process.exit(0)
}
const appPaths = require('../helpers/app-paths'),
const { tauriDir } = require('../helpers/app-paths'),
Runner = require('../runner'),
tauri = new Runner(appPaths),
tauri = new Runner(),
tauriConfig = require('../helpers/tauri-config')({
ctx: {
debug: true
}
})
const { bundle, ...cfg } = tauriConfig.tauri,
cfgDir = injector.configDir()
require('../generator').generate(tauriConfig.tauri)
require('../entry').generate(appPaths.tauriDir, tauriConfig, true)
require('../entry').generate(tauriDir, tauriConfig)
tauri.run(tauriConfig)

View File

@ -1,28 +1,49 @@
const
parseArgs = require('minimist'),
appPaths = require('../helpers/app-paths'),
log = require('../helpers/logger')('app:tauri')
logger = require('../helpers/logger'),
log = logger('app:tauri'),
warn = logger('app:tauri (init)', 'red')
/**
* @type {object}
* @property {boolean} h
* @property {boolean} help
* @property {string|boolean} f
* @property {string|boolean} force
* @property {boolean} l
* @property {boolean} log
*/
const argv = parseArgs(process.argv.slice(2), {
alias: {
h: 'help'
h: 'help',
f: 'force',
l: 'log'
},
boolean: ['h']
boolean: ['h', 'l']
})
if (argv.help) {
console.log(`
Description
Inits the Tauri template.
Inits the Tauri template. If Tauri cannot find the tauri.conf.js
it will create one.
Usage
$ tauri init
Options
--help, -h Displays this message
--force, -f Force init to overwrite [conf|template|all]
--log, l Logging [boolean]
`)
process.exit(0)
}
require('../template').inject(appPaths.tauriDir)
if (injector.injectTemplate()) {
log('Tauri template successfully installed')
const { inject } = require('../template')
const target = appPaths.tauriDir
if (inject(target, 'all', argv.f, argv.l)) {
log('tauri init successful')
} else {
warn('tauri init unsuccessful')
}

View File

@ -6,7 +6,7 @@ const cmd = process.argv[2]
if (!cmd || cmd === '-h' || cmd === '--help' || cmd === 'help') {
console.log(`
Description
Tauri CLI.
This is the Tauri CLI.
Usage
$ tauri ${cmds.join('|')}
Options

View File

@ -1,26 +0,0 @@
const init = {
embeddedServer: {},
bundle: {},
whitelist: {},
window: {},
security: {}
}
const defaultObject = {
embeddedServer: {
active: true
},
bundle: {
active: true
},
whitelist: {},
window: {
title: 'Quasar Tauri App'
},
security: {
csp: 'default-src data: filesystem: ws: http: https: \'unsafe-eval\' \'unsafe-inline\''
}
}
module.exports.init = init
module.exports.defaultObject = defaultObject

View File

@ -2,12 +2,11 @@ const compileTemplate = require('lodash.template'),
{ readFileSync, writeFileSync, ensureDir } = require('fs-extra'),
path = require('path')
module.exports.generate = (outDir, cfg, ctx, tauri = false) => {
module.exports.generate = (outDir, cfg) => {
const apiTemplate = readFileSync(path.resolve(__dirname, '../lib/tauri.js'), 'utf-8')
const apiContent = compileTemplate(apiTemplate)({
...cfg,
ctx: ctx,
confName: `${tauri ? 'tauri' : 'quasar'}.conf.js`
confName: 'tauri.conf.js'
})
ensureDir(outDir).then(() => {
writeFileSync(path.join(outDir, 'tauri.js'), apiContent, 'utf-8')

View File

@ -1,11 +1,12 @@
const
path = require('path'),
{ writeFileSync } = require('fs-extra')
{ writeFileSync } = require('fs-extra'),
{ tauriDir } = require('./helpers/app-paths')
module.exports.generate = tauriConfig => {
const
{ bundle, ...cfg } = tauriConfig,
outDir = path.resolve(__dirname, '..')
outDir = tauriDir
writeFileSync(path.join(outDir, 'config.json'), JSON.stringify(cfg))
writeFileSync(path.join(outDir, 'bundle.json'), JSON.stringify(bundle))
}

View File

@ -1,27 +1,27 @@
const
{ existsSync } = require('fs'),
path = require('path'),
resolve = path.resolve,
join = path.join
{ resolve, join, normalize, sep } = require('path')
/**
*
* @returns {{length}|*}
*/
function getAppDir() {
let dir = process.cwd()
let count = 0
while (dir.length && dir[dir.length - 1] !== path.sep) {
// only go up three folders max
while (dir.length && dir[dir.length - 1] !== sep && count <= 2) {
if (existsSync(join(dir, 'tauri.conf.js'))) {
return dir
}
dir = path.normalize(join(dir, '..'))
count++
dir = normalize(join(dir, '..'))
}
const
logger = require('./logger')
warn = logger('app:paths', 'red')
warn(`⚠️ Error. This command must be executed inside a Tauri project folder.`)
warn()
process.exit(1)
// just return the current directory
console.log(dir)
return process.cwd()
}
const appDir = getAppDir(),

View File

@ -4,7 +4,9 @@ const appPaths = require('./app-paths'),
module.exports = cfg => {
const tauriConf = require(appPaths.resolve.app('tauri.conf.js'))(cfg.ctx)
const config = merge({
build: {},
build: {
distDir: './dist'
},
ctx: {},
tauri: {
embeddedServer: {
@ -13,7 +15,9 @@ module.exports = cfg => {
bundle: {
active: true
},
whitelist: {},
whitelist: {
all: false
},
window: {
title: require(appPaths.resolve.app('package.json')).productName
},
@ -24,6 +28,5 @@ module.exports = cfg => {
}, tauriConf, cfg)
process.env.TAURI_DIST_DIR = appPaths.resolve.app(config.build.distDir)
return config
}

View File

@ -1,21 +1,20 @@
const
chokidar = require('chokidar'),
debounce = require('lodash.debounce'),
path = require('path')
path = require('path'),
{ readFileSync, writeFileSync } = require('fs-extra')
const
{ spawn } = require('./helpers/spawn'),
log = require('./helpers/logger')('app:tauri')
log = require('./helpers/logger')('app:tauri'),
onShutdown = require('./helpers/on-shutdown'),
{ readFileSync, writeFileSync } = require('fs-extra'),
generator = require('./generator')
generator = require('./generator'),
{ tauriDir } = require('./helpers/app-paths')
class TauriRunner {
constructor({ modeDir }) {
this.modeDir = modeDir
class Runner {
constructor() {
this.pid = 0
this.tauriWatcher = null
onShutdown(() => {
this.stop()
})
@ -23,7 +22,7 @@ class TauriRunner {
async run(cfg) {
process.env.TAURI_DIST_DIR = cfg.build.distDir
process.env.TAURI_CONFIG_DIR = tauriDir
const url = cfg.build.APP_URL
if (this.pid) {
@ -54,9 +53,9 @@ class TauriRunner {
// Start watching for tauri app changes
this.tauriWatcher = chokidar
.watch([
path.join(this.modeDir, 'src'),
path.join(this.modeDir, 'Cargo.toml'),
path.join(this.modeDir, 'build.rs')
path.join(tauriDir, 'src'),
path.join(tauriDir, 'Cargo.toml'),
path.join(tauriDir, 'build.rs')
], {
watchers: {
chokidar: {
@ -74,6 +73,7 @@ class TauriRunner {
async build(cfg) {
process.env.TAURI_DIST_DIR = cfg.build.distDir
process.env.TAURI_CONFIG_DIR = tauriDir
this.__manipulateToml(toml => {
this.__whitelistApi(cfg, toml)
@ -94,7 +94,7 @@ class TauriRunner {
})
if (cfg.ctx.debug || !cfg.ctx.targetName) {
// on debug mode or if not arget specified,
// on debug mode or if no target specified,
// build only for the current platform
return buildFn()
}
@ -125,7 +125,7 @@ class TauriRunner {
cargoArgs.concat(['--']).concat(extraArgs) :
cargoArgs,
this.modeDir,
tauriDir,
code => {
if (code) {
@ -169,7 +169,7 @@ class TauriRunner {
__manipulateToml(callback) {
const toml = require('@iarna/toml'),
tomlPath = path.join(this.modeDir, 'Cargo.toml'),
tomlPath = path.join(tauriDir, 'Cargo.toml'),
tomlFile = readFileSync(tomlPath),
tomlContents = toml.parse(tomlFile)
@ -195,4 +195,4 @@ class TauriRunner {
}
}
module.exports = TauriRunner
module.exports = Runner

View File

@ -1,13 +1,43 @@
const { copySync, renameSync, existsSync, mkdirSync } = require('fs-extra'),
path = require('path')
const { copySync, renameSync, existsSync, mkdirSync, removeSync } = require('fs-extra'),
{ resolve, join, normalize } = require('path'),
logger = require('./helpers/logger'),
log = logger('app:tauri', 'green'),
warn = logger('app:tauri (template)', 'red')
module.exports.inject = injectPath => {
if (existsSync(injectPath)) {
console.log(`Tauri dir (${injectPath}) not empty.`)
const injectConfFile = (injectPath, force, logging) => {
const dir = normalize(join(injectPath, '..'))
const path = join(dir, 'tauri.conf.js')
if (existsSync(path) && force !== 'conf' && force !== 'all') {
warn(`tauri.conf.js found in ${path}
Run \`tauri init --force conf\` to overwrite.`)
if (!force) return false
} else {
try {
removeSync(path)
copySync(resolve(__dirname, '../templates/conf/tauri.conf.js'), path)
} catch (e) {
if (logging) console.log(e)
return false
} finally {
if (logging) log('Successfully wrote tauri.conf.js')
}
}
}
const injectTemplate = (injectPath, force, logging) => {
if (existsSync(injectPath) && force !== 'template' && force !== 'all') {
warn(`Tauri dir (${injectPath}) not empty.
Run \`tauri init --force template\` to overwrite.`)
if (!force) return false
}
try {
removeSync(injectPath)
mkdirSync(injectPath)
copySync(resolve(__dirname, '../templates/rust'), injectPath)
} catch (e) {
if (logging) console.log(e)
return false
}
mkdirSync(injectPath)
copySync(path.resolve(__dirname, '../templates/rust'), injectPath)
const files = require('fast-glob').sync(['**/_*'], {
cwd: injectPath
})
@ -23,7 +53,39 @@ module.exports.inject = injectPath => {
}
return name
}).join('/')
renameSync(path.join(injectPath, rawPath), path.join(injectPath, targetRelativePath))
try {
renameSync(join(injectPath, rawPath), join(injectPath, targetRelativePath))
} catch (e) {
if (logging) console.log(e)
return false
} finally {
if (logging) log('Successfully wrote tauri template files')
}
}
}
/**
*
* @param {string} injectPath
* @param {string} type ['conf'|'template'|'all']
* @param {string|boolean} [force=false] - One of[false|'conf'|'template'|'all']
* @param {boolean} [logging=false]
* @returns {boolean}
*/
const inject = (injectPath, type, force = false, logging = false) => {
if (typeof type !== 'string' || typeof injectPath !== 'string') {
warn('- internal error. Required params missing.')
return false
}
if (type === 'conf' || type === 'all') {
injectConfFile(injectPath, force, logging)
}
if (type === 'template' || type === 'all') {
injectTemplate(injectPath, force, logging)
}
return true
}
module.exports = {
inject
}

View File

@ -1,7 +1,7 @@
{
"name": "@tauri-apps/tauri",
"version": "0.0.1-utility.8",
"description": "Multi-binding collection of libraries and templates for building Tauri",
"version": "0.0.1-utility.11",
"description": "Multi-binding collection of libraries and templates for building Tauri apps",
"bin": {
"tauri": "./mode/bin/tauri.js"
},

View File

@ -0,0 +1,30 @@
const
path = require('path'),
distDir = path.resolve(__dirname, './dist')
module.exports = function () {
return {
build: {
distDir: distDir,
APP_URL: 'http://localhost:4000' // must use a localhost server for now
},
ctx: {},
tauri: {
embeddedServer: {
active: true
},
bundle: {
active: true
},
whitelist: {
all: false
},
window: {
title: 'Tauri App'
},
security: {
csp: 'default-src data: filesystem: ws: http: https: \'unsafe-eval\' \'unsafe-inline\''
}
}
}
}

View File

@ -1,30 +1,31 @@
[package]
name = "app"
version = "0.1.0"
description = "A Quasar Tauri App"
author = []
description = "A Tauri App"
author = ["you"]
license = ""
repository = ""
default-run = "app"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tauri-ui = { path = "../node_modules/@quasar/tauri/bindings/rust" }
tauri-ui = { path = "../node_modules/@tauri-apps/tauri/bindings/rust" }
serde_json = "1.0.39"
serde = "1.0"
serde_derive = "1.0"
tiny_http = "0.6"
phf = "0.7.21"
includedir = "0.5.0"
tauri = { path = "../node_modules/@quasar/tauri/lib/rust" }
tauri = { path = "../node_modules/@tauri-apps/tauri/lib/rust" }
[features]
dev = ["tauri/dev"] # has no explicit dependencies
embedded-server = ["tauri/embedded-server"] # has no explicit dependencies
[package.metadata.bundle]
identifier = "com.quasar.dev"
identifier = "com.tauri.dev"
icon = ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"]
[[bin]]

View File

@ -9,4 +9,6 @@ Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
tauri.js
tauri.js
config.json
bundle.json

View File

@ -2,6 +2,7 @@ mod cmd;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
fn main() {
tauri::AppBuilder::new()

View File

@ -1,11 +1,11 @@
[package]
name = "cargo-tauri-bundle"
version = "1.0.0"
authors = ["George Burton <burtonageo@gmail.com>", "Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot <denjell@quasar.dev>"]
authors = ["George Burton <burtonageo@gmail.com>", "Lucas Fernandes Gonçalves Nogueira <lucas@quasar.dev>", "Daniel Thompson-Yvetot"]
license = "MIT/Apache-2.0"
keywords = ["bundle", "cargo", "tauri", "quasar"]
repository = "https://github.com/quasarframework/tauri"
description = "Wrap rust executables in OS-specific app bundles for Quasar-Tauri"
keywords = ["bundle", "cargo", "tauri"]
repository = "https://github.com/tauri-apps/tauri"
description = "Wrap rust executables in OS-specific app bundles for Tauri"
edition = "2018"
[dependencies]