Skip to content

Commit

Permalink
Add QMLify compiler to QMake
Browse files Browse the repository at this point in the history
Also add dependencies command to qmlify
  • Loading branch information
iBelieve committed Mar 27, 2016
1 parent 52c6550 commit 59dcd34
Show file tree
Hide file tree
Showing 11 changed files with 311 additions and 38 deletions.
13 changes: 10 additions & 3 deletions qmlify/bin/qmlify.bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ var args = require('yargs')
.default('polyfills', true)
.describe('polyfills', 'Include the Quickly polyfills library')
.describe('import', 'QML import path')
.default('depends', false)
.describe('depends', 'List all the dependencies of a particular file or directory')
.help('h')
.alias('h', 'help')
.argv
Expand All @@ -25,8 +27,13 @@ if (args.import) {
qmlify.addQMLImportPath(args.import)
}

if (args.outDir) {
qmlify.build_dir(source, args.outDir, options)
if (args.depends) {
const deps = qmlify.list_depends(source, args.outDir)
console.log(deps.join('\n'))
} else {
qmlify.build_file(source, args.outFile, options)
if (args.outDir) {
qmlify.build_dir(source, args.outDir, options)
} else {
qmlify.build_file(source, args.outFile, options)
}
}
18 changes: 17 additions & 1 deletion qmlify/src/basefile.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import {registerFileType} from './bundle'
import {require} from './dependencies'
import path from 'path'
import fs from 'fs'
import {ImportError} from './dependencies'
import {ImportError, Dependency} from './dependencies'
import _ from 'lodash'

export class BaseFile {
dependencies = {}

constructor(filename, bundle, {out_filename, useBabel, usePolyfills, ...options} = {}) {
this.bundle = bundle
this.useBabel = useBabel !== undefined ? useBabel : bundle.useBabel
Expand Down Expand Up @@ -32,6 +35,18 @@ export class BaseFile {
this.local_dirname = path.dirname(this.filename)
}

loadFromCache(cache) {
this.dependencies = _.mapValues(cache['dependencies'], json => Dependency.fromJSON(json))
}

get cache() {
return {
'src_filename': this.src_filename,
'out_filename': this.out_filename,
'dependencies': _.mapValues(this.dependencies, dep => dep.json)
}
}

relative(filename) {
return path.relative(this.out_dirname ? this.out_dirname : this.bundle.src_dirname, filename)
}
Expand All @@ -56,6 +71,7 @@ export class BaseFile {
build() {
this.text = fs.readFileSync(this.src_filename, 'utf8')
this.transform()
this.isBuilt = true
}

save() {
Expand Down
117 changes: 108 additions & 9 deletions qmlify/src/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ if (babelFile)

export class Bundle {
files = {}
config = {}
cache = {}

constructor(src_dirname, out_dirname, { name, parentBundle, usePolyfills = true, useBabel = true } = {}) {
this.name = name
Expand All @@ -33,12 +35,18 @@ export class Bundle {
load() {
this.qmldir = qmldir.load(this.src_dirname)

const quicklyFilename = path.resolve(this.src_dirname, 'quickly.json')
const quicklyFilename = this.resolve('quickly.json')

if (fs.existsSync(quicklyFilename))
this.config = JSON.parse(fs.readFileSync(quicklyFilename, 'utf-8'))
else
this.config = {}

if (this.out_dirname) {
const cacheFilename = path.resolve(this.out_dirname, '.qmlifycache')

if (fs.existsSync(cacheFilename)) {
this.cache = JSON.parse(fs.readFileSync(cacheFilename, 'utf-8'))
}
}
}

relative(filename) {
Expand Down Expand Up @@ -104,25 +112,58 @@ export class Bundle {
}
}

build(filename, options) {
getFile(filename, options) {
if (filename in this.files)
return this.files[filename]

for (const [regex, fileType] of fileTypes) {
if (filename.search(regex) !== NOT_FOUND) {
const file = new fileType(path.resolve(this.src_dirname, filename), this,
options)
file.build()
const cache = (this.parentBundle || this).cache[filename]

let file = null

if (cache) {
if (!options)
options = {}
options['out_filename'] = cache['out_filename']
file = new fileType(cache['src_filename'], this, options)
file.loadFromCache(cache)
} else {
file = new fileType(this.resolve(filename), this, options)
}

if (!fs.existsSync(file.src_filename))
throw new ImportError(`File doesn't exist: ${filename} (resolved to ${file.src_filename})`)

filesCache[file.src_filename] = file

this.files[file.filename] = file

if (this.parentBundle)
if (this.parentBundle) {
this.parentBundle.files[file.filename] = file
}

return file
}
}

throw new FileTypeError(`File type not recognized: ${filename}`)
return null
}

build(filename, options) {
const file = this.getFile(filename, options)

if (!file)
throw new FileTypeError(`File type not recognized: ${filename}`)

if (file.isBuilt)
return file

file.build();

(this.parentBundle || this).cache[file.filename] = file.cache

return file
}

save() {
Expand All @@ -136,6 +177,9 @@ export class Bundle {
fs.writeFileSync(path.resolve(this.out_dirname, 'quickly.json'),
JSON.stringify(bundleInfo, null, JSON_INDENT_LEVEL))

fs.writeFileSync(path.resolve(this.out_dirname, '.qmlifycache'),
JSON.stringify(this.cache, null, JSON_INDENT_LEVEL))

const resources = this.resources.map(resource => `\t<file>${resource}</file>`).join('\n')
const prefix = bundleInfo ? `/${bundleInfo.name}` : '/'
const qrc = `<!DOCTYPE RCC>\n<RCC version="1.0">\n\n<qresource prefix="${prefix}">\n${resources}\n</qresource>\n\n</RCC>\n`
Expand Down Expand Up @@ -176,6 +220,61 @@ export class Bundle {
get resources() {
return Object.values(this.files).map(file => path.relative(this.out_dirname, file.out_filename)).sort()
}

dependencies(source, base_dirname) {
let deps = []

if (!source) {
source = this.src_dirname

if (this.qmldir) {
deps = Object.values(this.qmldir.resources).map(resource => {
try {
return this.getFile(resource.filename).src_filename
} catch (error) {
if (error instanceof ImportError && resource.filename.startsWith('dependencies/')) {
return null
} else {
throw error
}
}
}).filter(filename => !!filename)
}
}

if (!base_dirname)
base_dirname = this.src_dirname

if (this.qmldir)
deps.push(this.resolve('qmldir'))
if (this.config)
deps.push(this.resolve('quickly.json'))

if (fs.existsSync(source) && isDir(source)) {
const files = fs.readdirSync(source)

for (const file of files) {
const filename = path.resolve(source, file)

deps = deps.concat(this.dependencies(filename))
}
} else {
source = path.resolve(this.out_dirname, source)
const file = this.getFile(path.relative(base_dirname, source))

if (file) {
deps.push(file.src_filename)

for (const dependency of Object.values(file.dependencies)) {
deps = deps.concat(this.dependencies(dependency.filename, this.out_dirname))
}
}
}

return deps.filter((item, index) => {
return deps.indexOf(item) === index
})
}
}

export function build(filename, bundle_or_options) {
Expand Down
20 changes: 19 additions & 1 deletion qmlify/src/dependencies.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,26 @@ export class Dependency {
this.importPath = importPath
this.file = file

if (file)
if (file) {
this.filename = file.filename
this.globals = file.exportedGlobals
}
}

static fromJSON(json) {
const dep = new Dependency()

dep.globals = json['globals']
dep.filename = json['filename']

return dep
}

get json() {
return {
'filename': this.filename,
'globals': this.globals
}
}

importQualifier(importAs) {
Expand Down
13 changes: 12 additions & 1 deletion qmlify/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import 'babel-polyfill'
import 'core-js/stage/3'
import 'source-map-support/register'

import {build, Bundle} from './bundle'
import './jsfile'
import './qmlfile'
import './qmlmodule'
import './npmmodule'
import {build, Bundle} from './bundle'
import {addImportPath} from './qmlmodule'
import {isDir} from './util'

export {build, registerFileType, Bundle} from './bundle'
export {BaseFile} from './basefile'
Expand All @@ -16,6 +17,16 @@ export function addQMLImportPath(path) {
addImportPath(path)
}

export function list_depends(source, out_dirname) {
const bundle = new Bundle(isDir(source) ? source : null, out_dirname)

if (isDir(source)) {
return bundle.dependencies()
} else {
return bundle.dependencies(source)
}
}

export function build_dir(src_dirname, out_dirname, options) {
const bundle = new Bundle(src_dirname, out_dirname, options)

Expand Down
18 changes: 16 additions & 2 deletions qmlify/src/jsfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@ export class JSFile extends BaseFile {
postHeader = templates.postHeader
footer = ''
globals = []
dependencies = {}

loadFromCache(cache) {
super.loadFromCache(cache)
this.globals = cache['globals']
}

get cache() {
return Object.assign({}, super.cache, {
'globals': this.globals
})
}

get importedGlobals() {
const globals = {}
Expand Down Expand Up @@ -43,7 +53,11 @@ export class JSFile extends BaseFile {

this.postHeader = this.postHeader.replace('FILENAME', this.basename)

if (this.usePolyfills) {
const bundle = this.bundle ? this.bundle.parentBundle || this.bundle : null

const exports = bundle && bundle.config && bundle.config.exports

if (this.usePolyfills && (!exports || exports['quickly-polyfills'])) {
this.injectRequire('quickly-polyfills')
}

Expand Down

0 comments on commit 59dcd34

Please sign in to comment.