In a gulp task, I try to copy files in a build folder.
gulp.task( addon, function() {
var a_addon_function = addon.split("_") ;
var addon_dirname = a_addon_function[1];
var dest_path = ( options.env === "tests" || ( options.env === "dist" && options.type === "premium" ) ) ? build_path + addon_dirname + "/" + addon_dirname : build_path + addon_dirname;
return gulp.src( [ "./plugins/addons/" + addon_dirname + "/**/*", "./plugins/_common/**/*", "./plugins/addons/_common/**/*" ] )
.pipe( gulp.dest( dest_path )
);
});
The file .htaccess is never copied. Why ? How to resolve this ?
Dots
If a file or directory path portion has a . as the first character,
then it will not match any glob pattern unless that pattern's
corresponding path part also has a . as its first character.
For example, the pattern a/.*/c would match the file at a/.b/c.
However the pattern a/*/c would not, because * does not start with a
dot character. You can make glob treat dots as normal characters by
setting dot:true in the options.
Set the option:
gulp.src('...…….', { dot: true })
so that the dot is treated like any other character. You should be able to use your original gulp.src then.
From node-glob documentation
Gulp copy the .htaccess file if I add the direct pathto this file : ./plugins/_common/.htaccess.
gulp.task( addon, function() {
var a_addon_function = addon.split("_") ;
var addon_dirname = a_addon_function[1];
var dest_path = ( options.env === "tests" || ( options.env === "dist" && options.type === "premium" ) ) ? build_path + addon_dirname + "/" + addon_dirname : build_path + addon_dirname;
return gulp.src( [ "./plugins/addons/" + addon_dirname + "/**/*", "./plugins/_common/**/*", "./plugins/_common/.htaccess", "./plugins/addons/_common/**/*" ] )
.pipe( gulp.dest( dest_path )
);
});
Maybe it is not copied because .htaccess has not got extension file.
Related
I.
I´m trying to make a skeleton of a app to read and write files in Neutralino.js but...
Now i´m stopped by trying to read the content of a selected file to a variable.
I think the file is corrected selected, but... when using the Neutralino.filesystem.readFile it reads the text file whitout respecting the end of line carriege.
The conteudo_edm contains all the file content but just as a string, hope to be like a array, but there is no line breaks...
Any ideia?
async function lerN() {
let entries = await Neutralino.os.showOpenDialog('Abrir um ficheiro', {
filters: [
{ name: 'ISPOL', extensions: ['edm', 'EDM'] },
{ name: 'All files', extensions: ['*'] }
]
});
ficheiro = entries + ''
ficheiro = ficheiro.replace(/\\/g, "/")
conteudo_edm = await Neutralino.filesystem.readFile(entries[0]); //Aqui está a juntar tudo numa string!!!
console.log(conteudo_edm)
document.getElementById("lbl_ficheiroaberto").textContent = "Ficheiro aberto : " + ficheiro;
console.log("entries__")
console.log(entries)
console.log("entries__")
filtra_ficheiro(entries[0])
//document.getElementById("lbl_apagar").textContent = "estou a ler: " + ficheiro
}
Try Using Split Instead Of Replace.
This Worked For Me:
async function lerN() {
let entries = await Neutralino.os.showOpenDialog('Abrir um ficheiro', {
filters: [
{ name: 'ISPOL', extensions: ['edm', 'EDM'] },
{ name: 'All files', extensions: ['*'] }
]
});
ficheiro = entries + ''
ficheiro = ficheiro.split(/\r?\n/); # This is what i tried.
conteudo_edm = await Neutralino.filesystem.readFile(entries[0]);
console.log(conteudo_edm)
document.getElementById("lbl_ficheiroaberto").textContent = "Ficheiro aberto : " + ficheiro;
console.log("entries__")
console.log(entries)
console.log("entries__")
filtra_ficheiro(entries[0])
}
I'd like to know if is there any way or library available to import all modules from a folder without know the names.
Example:
└── routes/
└──── x.routes.ts
└──── y.routes.ts
└──── z.routes.ts
└──── ...
Then makes those available from mymodule.ts for example.
Unfortunately, import works only with explicit paths.
But webpack provides the following feature:
https://webpack.js.org/guides/dependency-management/#context-module-api
I was able to do reading the files path from a folder with fs.readDirSync()
Then importing them like:
const { default: Module } = require( _module.path ) (modules that was exported by default) all into an iterator.
I share my entire solution:
This abstracted function returns all modules paths in a directory based on a dir, a criteria for get them and an exclude list of filenames:
export const getModules = ( params: IM ): IModule[] => {
const { dir, criteria, excludeList } = params
let { modulesList=[] } = params
const modulePrefix: string = getModulePrefix() // includes slash
const modulesDir: string = path.resolve( `${modulePrefix}${dir}` )
const modules: string[] = fs.readdirSync( modulesDir )
const r: RegExp[] = ( process.platform === 'win32' ) ? [/\\\w+$/, /^\\/] : [/\/\w+$/, /^\//]
modules.forEach(( _module: string ) => {
const modulePath: string = path.resolve( modulesDir, _module )
if ( fs.statSync(modulePath).isDirectory() ) {
// Recursive call
modulesList = getModules({ dir:modulePath, criteria, excludeList, modulesList })
} else if ( criteria.test(_module) && !excludeList.includes(_module) ) {
modulesList.push({
path: modulePath,
filename: _module,
type: modulesDir.match(r[0])![0].replace(r[1], '')
})
}
})
return modulesList
}
The IM params types:
interface IM {
readonly dir: string
readonly criteria: RegExp
readonly excludeList: string[]
modulesList?: IModule[]
}
This is a cross-platform one. It will works on unix and windows based systems.
The modules types returned are described by:
export interface IModule {
path: string
filename: string
type: string
}
And the function above is used by other functions (not abstracted) that get those module paths based in some rules as follows (in this case, for middlewares types in middlewares folder):
export const getMiddlewares = (): IModule[] => {
const dir: string = './src/middlewares'
const criteria: RegExp = /^.+\.(ts|js)$/
const excludeList: string[] = [
'tmpl.ts',
'tmpl.js'
]
return getModules({ dir, criteria, excludeList })
}
Then modules can be imported as resources like (I have this in another function called loadResources()):
// modulePaths has IModule[] as a type
modulePaths.forEach(( _module: IModule ) => {
const { default: Module } = require( _module.path )
if ( Module instanceof Function ) {
const $resource: Resource = Module( service )
if ( callback instanceof Function )
callback( $resource )
;
} else {
console.warn( chalk.yellow(
`WARNING: #${_module.type} ‚Üí ${_module.filename.replace(/\.(ts|js)$/, '')} must export a function by default`
))
}
})
I Hope to help to any one else who is searching for this solution.
The getModules() function is re-usable and it is abstracted to import any thing you want based on your own rules.
Source code can be reviewed in my repository: https://github.com/bananasplit-js/bananasplit-js/blob/65d7cdd9dca4c89f8f32a7ae13c63ed098dab7c2/src/providers/core/helpers/resources.ts#L43
My yeoman generator copies files from template to destination path:
this.fs.copyTpl(
this.templatePath(),
this.destinationPath(), {
appName: this.props.appName
});
During project generation, I need to assign value of this.props.appName to some of filenames.
Unfortunately I can't do this that way like I could do inside this files:
<%=appName%>-project.sln
All files that need to be renamed have appTemplate in their names, so what I need to do is simply replace appTemplate with value of this.props.appName.
Can I somehow configure copyTpl to rename some of files while copying them to another destination?
OK, I found a solution. According to yeoman docs:
Any generator author can register a transformStream to modify the file path and/or the content.
Using this method:
this.registerTransformStream();
What that means is I can pipe all generated files through some script:
var rename = require("gulp-rename");
//other dependecies...
module.exports = yeoman.Base.extend({
//some other things generator do...
writing: function() {
var THAT = this;
this.registerTransformStream(rename(function(path) {
path.basename = path.basename.replace(/(666replacethat666)/g, THAT.props.appName);
path.dirname = path.dirname.replace(/(666replacethat666)/g, THAT.props.appName);
}));
this.fs.copyTpl(
this.templatePath(),
this.destinationPath(), {
appName: this.props.appName
});
}
});
This script will pipe all files through gulp-rename, changing 666replacethat666 to something more intelligent.
If you cannot use registerTransformStream because you are using the composeWith() feature in Yeoman (which disconnects transform stream registrations), you can use the processDestinationPath, which works when you select multiple files (not when you specify a specific file in the first argument, for some reason).
this.fs.copyTpl(
this.templatePath("**/{.*,*}"),
this.destinationPath(),
{ /* usually your prompt answers are here */ },
{},
{
processDestinationPath: (filePath: string) =>
filePath.replace(/somedir\/a-file.js/g, 'newdir/better-filename.js'),
},
);
Source to documentation options: https://yeoman.github.io/generator/actions_fs.html#.copyTemplate
Which is based on https://github.com/SBoudrias/mem-fs-editor#copyfrom-to-options-context-templateoptions-
registerTransformStream with gulp-rename is still an issue. However, I get it working with glob.
const glob = require('glob');
writing() {
const files = glob.sync('**', { dot: true, nodir: true, cwd: this.templatePath() })
for (let i in files) {
this.fs.copyTpl(
this.templatePath(files[i]),
this.destinationPath( this.props.destinationFolderPath + '\\' + files[i].replace(/__fileName__/g,this.props.fileName)),
this.props
)
}
}
After copy, iterate over the paths of the output dir and regex replace all occurrences.
const getReplacement = (base, pathRel, match, replace) => {
let pathRelNew = pathRel.replace(match, replace);
let oldPathAbs = path.join(base, pathRel);
let newPathAbs = path.join(base, pathRelNew);
if (oldPathAbs != newPathAbs) {
return {
oldPath: oldPathAbs,
newPath: newPathAbs
}
}
}
const getReplacementsRecursive = (base, match, replace, replacements = []) => {
let pathsRel = fs.readdirSync(base);
pathsRel.forEach(pathRel => {
if (fs.statSync(path.join(base, pathRel)).isDirectory()) {
replacements = getReplacementsRecursive(path.join(base, pathRel), match, replace, replacements);
var replacement = getReplacement(base, pathRel, match, replace)
if (replacement) replacements.push(replacement);
} else {
var replacement = getReplacement(base, pathRel, match, replace)
if (replacement) replacements.push(replacement);
}
});
return replacements;
};
function replaceMatches(dir, match, replace) {
var replacements = getReplacementsRecursive(dir, match, replace);
replacements.forEach(function(replacement) {
fs.renameSync(replacement.oldPath, replacement.newPath);
});
}
module.exports = class extends Generator {
// ...
writing() {
// don't forget to set the output directory
let OUTPUT_DIR = "./out";
// this.fs.copyTpl(...);
// setTimeout is used to give some time for the copyTpl to finish
setTimeout(
() => {
var match = new RegExp( "666replacethat666", 'g' );
replaceMatches(OUTPUT_DIR, match, this.props.appName);
}, 1000);
}
}
How can i add "/" on end of all url if there is not on Node JS / Express ?
Thank you in advance
All you need to do is check whether the string last character is "/", and if its not add it.
like this:
var addSlash = function( str ) {
return str.substr(-1) !== "/" ? ( str + "/" ) : str
}
var url = require('url');
function addSlash = function (str) {
var u = url.parse(str);
if (u.pathname.substr(-1) !== "/") {
u.pathname += "/";
}
return url.format(u);
}
lastIndexOf return the last position where a slash is, and if it isn't at the end of the string, we add a slash to the url.
function addSlash(url) {
return url.lastIndexOf("/") == url.length - 1 ? url + "/" : url:
}
No modules required.
I'm trying to copy 2 folders onto a single build folder and for the second path I want to copy whole libs folder including libs folder itself to destination.
var paths = {
'standalone' : '../app-ui/assets/js',
'standalone_libs' : '../app-ui/libs',
'destination' : '../SomeFolder'
}
gulp.task('folder-copy', function() {
return gulp.src([paths.standalone_js + '/*', paths.standalone_libs + '/*']).pipe(gulp.dest(paths.destination));
});
Structure according to code
->SomeFolder
->app.js [ file from ../app-ui/assets/js ]
-> angular/angular.js [ file from ../app-ui/libs ]
-> lodash/lodash.js [ file from ../app-ui/libs ]
Actual Structure wanted
->SomeFolder
->app.js [ file from ../app-ui/assets/js ]
-> libs
-> angular/angular.js [ file from ../app-ui/libs ]
-> lodash/lodash.js [ file from ../app-ui/libs ]
You could specify the base in gulp.src :
return gulp.src(['some/path/app/*', 'libs/**/*'], {base: '.'})
.pipe(gulp.dest('build'));
This will copy all your files in libs, with the directory structure intact. But the directory structure will be preserved for app.js also...
I would just do two separate copy.
You can use merge-stream. There's a recipe in gulp repository. It would boil down to something like this :
var merge = require('merge-stream')
var libs= gulp.src('libs/**/*', {base: '.'})
.pipe(gulp.dest('build'));
var app = gulp.src('app.js')
.pipe(gulp.dest('build'));
return merge(libs, app);
Try removing the /* because this means the whole content inside the folder is what you want.
So for the libs, I would not add the /* like follows
return gulp.src([paths.standalone_js + '/*', paths.standalone_libs ]).pipe(gulp.dest(paths.destination));
What about changing this:
var paths = {
'standalone' : '../app-ui/assets/js',
'standalone_libs' : '../app-ui/libs',
'destination' : '../SomeFolder'
}
to this:
var paths = {
'standalone' : '../app-ui/assets/js',
'standalone_libs' : '../app-ui/(libs)',
'destination' : '../SomeFolder'
}