efdir
Version:
394 lines (326 loc) • 8.12 kB
JavaScript
const fs = require("fs")
const beau = require("beautify")
const path = require("path")
const {
set_dict_via_pl,
get_val_via_pl,
deflatten_from_entries,
flatten_to_entries,
} = require('nvjson')
const strip_comments = require("strip-json-comments")
function transcodec(s,src_codec,dst_codec) {
let src_buf = Buffer.from(s,src_codec)
let dst_str = src_buf.toString(dst_codec)
return(dst_str)
}
function rjson(fn) {
let buf = fs.readFileSync(fn)
let s = buf.toString()
s = strip_comments(s)
let d = JSON.parse(s)
return(d)
}
function wjson(fn,js) {
let s =JSON.stringify(js)
s = beau(s,{format: 'json'})
fs.writeFileSync(fn,s)
}
function rfile(fn,codec) {
let buf = fs.readFileSync(fn)
let s = buf.toString(codec)
return(s)
}
function wfile(fn,s,codec) {
fs.writeFileSync(fn,s,codec)
}
function lsdir(dn) {
dn = path.resolve(dn);
return(fs.readdirSync(dn))
}
function getWalkFilter(filter) {
if(typeof(filter)==="string") {
filter = WALK_FILTERS[filter]
} else {
}
return(filter)
}
function pathLength(p) {
let arr = p.split("/")
return(arr.length)
}
function pathDepth(p,root) {
let rlen = pathLength(root)
let plen = pathLength(p)
return(plen - rlen)
}
function walkdirInternal(root,files) {
files = files || []
let dir = path.resolve(root)
if (!fs.existsSync(dir)) return files
if (fs.statSync(dir).isDirectory()) {
files.push(dir)
fs.readdirSync(dir)
.forEach(function (name) {
let absPath = path.resolve(path.join(dir, name))
walkdirInternal(absPath,files)
})
} else {
files.push(dir)
}
return files
}
function walkdir(root, filter) {
filter = filter || WALK_FILTERS['no-dot-files']
filter = getWalkFilter(filter)
let files = walkdirInternal(root)
files = files.filter(filter)
return files
}
function path_to_pl(p) {
let sep = path.sep?path.sep:'/'
let arr= p.split(sep)
return(arr)
}
function load_file_content(p) {
let content = rfile(p,'latin1')
return(content)
}
function write_file_content(p,content) {
wfile(p,content,'latin1')
}
function path_to_entry(fn,p,copy_content) {
let cond = is_dir(p)
fn = path.resolve(fn)
let kp = p.substr(fn.length)
let kpl = path_to_pl(kp)
kpl = kpl.filter(r=>(r!==''))
let entry =[JSON.stringify(kpl),{}]
if(cond) {
//严格的做法应该在walkdir 里面就实现
} else {
copy_content = (copy_content === undefined)?false:copy_content
if(copy_content) {
entry[1] = load_file_content(p)
} else {
entry[1] = ""
}
}
return(entry)
}
function pl_to_path(pl) {
let sep = path.sep?path.sep:'/'
return(pl.join(sep))
}
function entry$key_to_path(k) {
let pl = JSON.parse(k)
return(pl_to_path(pl))
}
function entry_to_pl$entry(entry,prefix) {
prefix = path.resolve(prefix)
let k = entry$key_to_path(entry[0])
k = path.join(prefix,k)
let v = entry[1]
return([k,v])
}
function dir_to_json(fn,d) {
d = (d===undefined)?{}:d
let copy_content = (d.copy_content === undefined)?false:d.copy_content;
fn = (fn===undefined)?'./':fn
fn = path.resolve(fn)
paths = walkdir(fn,WALK_FILTERS.none)
entries = paths.map(r=>path_to_entry(fn,r,copy_content))
cfg = deflatten_from_entries(entries)
return(cfg)
}
function mkdir$touch_with_pl$entry(entry) {
let p = entry[0]
let content = entry[1]
let cond = (typeof(content) === 'string')
let dirname = cond?path.dirname(p):p
if( !fs.existsSync(dirname)){fs.mkdirSync(dirname)} else {}
if(cond) {
wfile(p,content,'latin1')
} else {
}
return(entry)
}
function dict_to_pl$entries(j,dstfn="./") {
let entries = flatten_to_entries(j)
entries = entries.map(r=>entry_to_pl$entry(r,dstfn))
return(entries)
}
function json_to_dir(j,dstfn="./") {
let entries = flatten_to_entries(j)
entries = entries.map(r=>entry_to_pl$entry(r,dstfn))
entries = entries.map(r=>mkdir$touch_with_pl$entry(r))
return(entries)
}
function cfg_to_dir(srcfn,dstfn="./") {
let j = rjson(srcfn)
return(json_to_dir(j,dstfn))
}
function walkDirInRange(root,d={start:0},filter) {
let files = walkdir(root,filter)
let si = d.start
let ei = d.end ||files.length
files = files.filter(function(x){
let depth = pathDepth(x,path.resolve(root))
let cond = ((depth>= si) && (depth<ei))
return(cond)
})
return(files)
}
function is_nodot_in_path(p) {
let pls = path_to_pl(p)
let cond = pls.every(
r=>(path.basename(r)[0] !== ".")
)
return(cond)
}
WALK_FILTERS = {
'no-dot-files':function (x) {
//路径中没有隐藏文件夹
return(is_nodot_in_path(x))
},
'none':function (x) {
return(true)
},
'only-dot-files':function (x) {
x = path.basename(x)
return(x[0]==".")
},
'only-dir':function (x) {
return(fs.statSync(x).isDirectory())
},
'only-file':function (x) {
return(!fs.statSync(x).isDirectory())
}
}
function is_file(p) {
try {
p = fs.realpathSync(p) // for symbolLink
let stat = fs.lstatSync(p)
return(stat.isFile())
} catch(err) {
//for temp dir such as /proc/6888/fd/pipe:[21469865]
return(true)
}
}
function is_dir(p) {
try {
p = fs.realpathSync(p) // for symbolLink
let stat = fs.lstatSync(p)
return(stat.isDirectory())
} catch(err) {
//for temp dir such as /proc/6888/fd/pipe:[21469865]
return(false)
}
}
function get_ance_pls(p) {
let sep = path.sep?path.sep:'/'
let arr= p.split(sep)
let pls = []
for(let i =1;i<=arr.length;i++) {
let pl = arr.slice(0,i)
pls.push(pl)
}
return(pls)
}
function get_ance_paths(p) {
let sep = path.sep?path.sep:'/'
let ps = get_ance_pls(p)
ps = ps.map(r=>r.join(sep))
ps = ps.filter(r=>r!=='')
return(ps)
}
function is_root_path(p) {
let sep = path.sep?path.sep:'/'
return(p===sep)
}
function is_path_end_with_sep(p) {
let sep = path.sep?path.sep:'/'
let cond = p[p.length-1] === sep
return(cond)
}
function mkdirp(p) {
let paths = get_ance_paths(p)
if(paths.length === 1) {
} else {
if(is_path_end_with_sep(paths[paths.length - 1])) {
paths = paths.slice(0,paths.length - 1)
} else {
}
}
paths.forEach(
r=>{
fs.mkdirSync(r)
}
)
return(paths)
}
function mkdirp_and_touch(p) {
let paths = get_ance_paths(p)
if(paths.length === 1) {
if(is_path_end_with_sep(paths[0])) {
fs.mkdirSync(paths[0])
} else {
wfile(paths[0],'')
}
} else {
let lst = paths[paths.length - 1]
let npaths = paths.slice(0,paths.length - 1)
npaths.forEach(r=>{fs.mkdirSync(r)})
if(is_path_end_with_sep(lst)) {
} else {
wfile(lst,'')
}
}
return(paths)
}
function rplc_ext(fn,new_ext) {
let d = path.parse(fn);
let nfn = path.resolve(d.dir,d.name+"."+new_ext);
return(nfn);
}
function rplc_name(fn,new_name) {
let d = path.parse(fn);
let nfn = path.resolve(d.dir,new_name+d.ext);
return(nfn);
}
function unparse(d) {return(path.resolve(d.dir,d.name+d.ext))}
module.exports = {
get_ance_pls,
get_ance_paths,
is_root_path,
is_path_end_with_sep,
mkdirp,
mkdirp_and_touch,
transcodec,
is_file,
is_dir,
path_to_pl,
pl_to_path,
path_to_entry,
dir_to_json,
wfile:wfile,
rfile:rfile,
wjson:wjson,
rjson:rjson,
lsdir:lsdir,
walkdir:walkdir,
walkDirInRange:walkDirInRange,
WALK_FILTERS:WALK_FILTERS,
entry$key_to_path,
entry_to_pl$entry,
mkdir$touch_with_pl$entry,
dict_to_pl$entries,
json_to_dir,
cfg_to_dir,
rplc_ext,
rplc_name,
unparse,
}
/*
*
*
*/