2021-04-10 03:18:32 +02:00
import ScriptUtils from "./ScriptUtils" ;
import { Utils } from "../Utils" ;
import { lstatSync , readdirSync , readFileSync , writeFileSync } from "fs" ;
Utils . runningFromConsole = true
import LayerConfig from "../Customizations/JSON/LayerConfig" ;
import { error } from "util" ;
import * as licenses from "../assets/generated/license_info.json"
import SmallLicense from "../Models/smallLicense" ;
import LayoutConfig from "../Customizations/JSON/LayoutConfig" ;
2021-04-10 03:50:44 +02:00
import { LayerConfigJson } from "../Customizations/JSON/LayerConfigJson" ;
2021-04-10 03:18:32 +02:00
// This scripts scans 'assets/layers/*.json' for layer definition files and 'assets/themes/*.json' for theme definition files.
// It spits out an overview of those to be used to load them
// First, remove the old file. It might be buggy!
writeFileSync ( "./assets/generated/known_layers_and_themes.json" , JSON . stringify ( {
"layers" : [ ] ,
"themes" : [ ]
} ) )
const layerFiles = ScriptUtils . readDirRecSync ( "./assets/layers" )
. filter ( path = > path . indexOf ( ".json" ) > 0 )
. filter ( path = > path . indexOf ( "license_info.json" ) < 0 )
. map ( path = > {
try {
const parsed = JSON . parse ( readFileSync ( path , "UTF8" ) ) ;
return parsed
} catch ( e ) {
console . error ( "Could not parse file " , path , "due to " , e )
}
} )
2021-04-10 03:50:44 +02:00
const themeFiles : any [ ] = ScriptUtils . readDirRecSync ( "./assets/themes" )
2021-04-10 03:18:32 +02:00
. filter ( path = > path . indexOf ( ".json" ) > 0 )
. filter ( path = > path . indexOf ( "license_info.json" ) < 0 )
. map ( path = > {
return JSON . parse ( readFileSync ( path , "UTF8" ) ) ;
} )
writeFileSync ( "./assets/generated/known_layers_and_themes.json" , JSON . stringify ( {
"layers" : layerFiles ,
"themes" : themeFiles
} ) )
console . log ( "Discovered " , layerFiles . length , "layers and " , themeFiles . length , "themes\n" )
console . log ( " ---------- VALIDATING ---------" )
// ------------- VALIDATION --------------
const licensePaths = [ ]
for ( const i in licenses ) {
licensePaths . push ( licenses [ i ] . path )
}
const knownPaths = new Set < string > ( licensePaths )
2021-04-10 03:50:44 +02:00
function validateLayer ( layerJson : LayerConfigJson , context? : string ) : number {
2021-04-10 03:18:32 +02:00
let errorCount = 0 ;
2021-04-10 03:50:44 +02:00
if ( layerJson [ "overpassTags" ] !== undefined ) {
2021-04-10 03:18:32 +02:00
errorCount ++
2021-04-10 03:50:44 +02:00
console . error ( "CRIT! Layer " , layerJson . id , "still uses the old 'overpassTags'-format. Please use 'source: {osmTags: <tags>}' instead" )
2021-04-10 03:18:32 +02:00
}
2021-04-10 03:50:44 +02:00
try {
const layer = new LayerConfig ( layerJson , "test" , true )
const images = Array . from ( layer . ExtractImages ( ) )
const remoteImages = images . filter ( img = > img . indexOf ( "http" ) == 0 )
for ( const remoteImage of remoteImages ) {
console . error ( "Found a remote image:" , remoteImage , "in layer" , layer . id )
2021-04-10 03:18:32 +02:00
errorCount ++
}
2021-04-10 03:50:44 +02:00
for ( const image of images ) {
if ( ! knownPaths . has ( image ) ) {
console . error ( "Image with path" , image , "not found or not attributed; it is used in" , layer . id , context === undefined ? "" : ` in a layer defined in the theme ${ context } ` )
errorCount ++
}
}
2021-04-10 14:25:06 +02:00
2021-04-10 03:50:44 +02:00
} catch ( e ) {
console . error ( "Layer " , layerJson . id ? ? JSON . stringify ( layerJson ) . substring ( 0 , 50 ) , " is invalid: " , e )
return 1
2021-04-10 03:18:32 +02:00
}
return errorCount
}
2021-04-10 03:50:44 +02:00
2021-04-10 03:18:32 +02:00
let layerErrorCount = 0
const knownLayerIds = new Set < string > ( ) ;
for ( const layerFile of layerFiles ) {
knownLayerIds . add ( layerFile . id )
2021-04-10 03:50:44 +02:00
layerErrorCount += validateLayer ( layerFile )
2021-04-10 03:18:32 +02:00
}
let themeErrorCount = 0
for ( const themeFile of themeFiles ) {
for ( const layer of themeFile . layers ) {
2021-04-10 03:50:44 +02:00
if ( typeof layer === "string" ) {
if ( ! knownLayerIds . has ( layer ) ) {
2021-04-10 03:18:32 +02:00
console . error ( "Unknown layer id: " , layer )
themeErrorCount ++
}
2021-04-10 15:53:47 +02:00
} else {
if ( layer . builtin !== undefined ) {
if ( ! knownLayerIds . has ( layer . builtin ) ) {
console . error ( "Unknown layer id: " , layer . builtin , "(which uses inheritance)" )
themeErrorCount ++
}
} else {
// layer.builtin contains layer overrides - we can skip those
layerErrorCount += validateLayer ( layer , themeFile . id )
}
2021-04-10 03:18:32 +02:00
}
}
2021-04-10 03:50:44 +02:00
2021-04-10 15:53:47 +02:00
themeFile . layers = themeFile . layers
. filter ( l = > typeof l != "string" ) // We remove all the builtin layer references as they don't work with ts-node for some weird reason
. filter ( l = > l . builtin === undefined )
2021-04-10 03:50:44 +02:00
2021-04-10 03:18:32 +02:00
try {
2021-04-10 03:50:44 +02:00
const theme = new LayoutConfig ( themeFile , true , "test" )
2021-04-10 14:25:06 +02:00
if ( theme . id !== theme . id . toLowerCase ( ) ) {
2021-04-10 03:50:44 +02:00
console . error ( "Theme ids should be in lowercase, but it is " , theme . id )
2021-04-10 03:18:32 +02:00
}
} catch ( e ) {
console . error ( "Could not parse theme" , themeFile [ "id" ] , "due to" , e )
themeErrorCount ++ ;
}
}
2021-04-10 14:25:06 +02:00
if ( layerErrorCount + themeErrorCount == 0 ) {
console . log ( "All good!" )
} else {
const msg = ( ` Found ${ layerErrorCount } errors in the layers; ${ themeErrorCount } errors in the themes ` )
2021-04-10 15:01:28 +02:00
if ( process . argv . indexOf ( "--no-fail" ) >= 0 ) {
console . log ( msg )
} else {
throw msg ;
}
2021-04-10 14:25:06 +02:00
}