How do you get metalsmith to run a bash script? Can you even do that?
My build.js is pretty simple, but I want to delete something from the build folder after everything is compiled.
var Metalsmith = require('metalsmith'),
copy = require('metalsmith-copy'),
define = require('metalsmith-define'),
markdown = require('metalsmith-markdown'),
permalinks = require('metalsmith-permalinks'),
static = require('metalsmith-static'),
templates = require('metalsmith-templates');
Metalsmith(__dirname)
.source('./pages')
.use(static(require('./config/assets')))
.use(static(require('./config/rootFiles')))
.use(define(require('./config/define')))
.use(markdown())
.use(permalinks())
.use(templates(require('./config/templates')))
.destination('./build')
.build(function (err) {
if (err) {
throw err
}
})
So if I keep a bash script in config/cleanup.sh, how do I execute it after the .build()?
Node js fs utils
If you're just looking to delete files and folders then Node.js has filesystem utils that can do it for you:
var fs = require('fs');
// file
fs.unlink('/path/to/filename.txt', callback);
// directory
fs.rmdir('/path/to/dirname', callback);
Execute bash script (or other commands)
If you really want to run a bash script then child_process.exec might help you.
(example from: http://www.dzone.com/snippets/execute-unix-command-nodejs)
var sys = require('sys')
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { sys.puts(stdout) }
exec('./bash_script.sh', puts);
You could use https://github.com/pjeby/gulpsmith and use another gulp plugin (e.g. https://www.npmjs.com/package/gulp-clean) to delete your files.
Related
I would like to build a CLI application using Deno however I can't find a module that allows me to keep prompting the user for interaction similar to command line applications to the REPL module on Node.js
Any suggestions?
You can use std/io to build a REPL.
import { readLines } from "https://deno.land/std#v0.52.0/io/bufio.ts";
async function read() {
// Listen to stdin input, once a new line is entered return
for await(const line of readLines(Deno.stdin)) {
console.log('Received', line)
return line;
}
}
console.log('Start typing');
while(true) {
await read()
}
You can build from here, process each line, add commands and so on.
If you just want one line,you can do this
import { readLines } from "https://raw.githubusercontent.com/denoland/deno/master/std/io/bufio.ts";
const word = (await readLines(Deno.stdin).next()).value.trim()
console.log(`You typed: ${word}`)
D:\WorkSpace\VSCode\deno-play>deno run -A main.ts
hello
You typed: hello
Current denoland lib Commits on Jun 19, 2020
Im trying let the user Upload a txt file and then let him click a button "analyze" and then perform some analysis.
I have the app working locally, Im using FS.Collection and FileSystem however I had several problems deploying to meteor.com. Here is my collection:
FS.debug = true;
Uploads = new FS.Collection('uploads', {
stores: [new FS.Store.FileSystem('uploads')]
});
and here is how I try to read the uploaded file:
var fs = Npm.require('fs');
var readedFile = fs.readFileSync(process.env.PWD+'/.meteor/local/cfs/files/uploads/+file.copies.uploads.key, 'utf-8');
The above works in local but not after I deploy to meteor.com, in the debug messages I see something like this: Error: ENOENT, no such file or directory
So I do not know how to read the file when the app is deployed, how would you do it?, or do you think I should deploy the app to Amazon EC2? Im afraid to deploy to amazon and have the same problem...
Short example of using http to download a file that was uploaded via collectionFS.
var file = Uploads.findOne({ _id: myId }); // or however you find it
HTTP.get(file.url(),function(err,result){
// this will be async obviously
if ( err ) console.log("Error "+err+" downloading file"+myId);
else {
var content = result.content; // the contents of the file
// now do something with it
}
});
Note that you must meteor add http to get access to the http package.
This is probably the package you want:
https://github.com/tomitrescak/meteor-uploads
it has a nice UI too and much less trouble than FSCollection.
I'm looking for the canonical way to access the directory that belongs to a running extension. At the moment I have this kludge. It allows me to access a .json located in the same directory as main.js.
var support_dir = brackets.app.getApplicationSupportDirectory(),
precursor_path,
precursor_file = "package.json"; // where this represents some config file.
support_dir += "/extensions/user/zeffii.precursor/";
precursor_path = support_dir + precursor_file;
var prototypes;
$.getJSON(precursor_path, function (data) {
prototypes = data;
});
This should work:
var ExtensionUtils = brackets.getModule("utils/ExtensionUtils");
var path = ExtensionUtils.getModulePath(module);
(Where module comes from the define(function (require, exports, module) { at the top of your extension module).
I have some jar file (custom) which I need to publish to Sonatype Nexus repository from Groovy script.
I have jar located in some path on machine where Groovy script works (for instance: c:\temp\module.jar).
My Nexus repo url is http://:/nexus/content/repositories/
On this repo I have folder structure like: folder1->folder2->folder3
During publishing my jar I need to create in folder3:
New directory with module's revision (my Groovy script knows this revision)
Upload jar to this directory
Create pom, md5 and sha1 files for jar uploaded
After several days of investigation I still have no idea how to create such script but this way looks very clear instead of using direct uploading.
I found http://groovy.codehaus.org/Using+Ant+Libraries+with+AntBuilder and some other stuff (stackoverflow non script solution).
I got how to create ivy.xml in my Groovy script, but I don't understand how to create build.xml and ivysetting.xml on the fly and setup whole system to work.
Could you please help to understand Groovy's way?
UPDATE:
I found that the following command works fine for me:
curl -v -F r=thirdparty -F hasPom=false -F e=jar -F g=<my_groupId> -F a=<my_artifactId> -F v=<my_artifactVersion> -F p=jar -F file=#module.jar -u admin:admin123 http://<my_nexusServer>:8081/nexus/service/local/repositories
As I understand curl perform POST request to Nexus services. Am I correct?
And now I'm trying to build HTTP POST request using Groovy HTTPBuilder.
How I should transform curl command parameters into Groovy's HTTPBuilder request?
Found a way to do this with the groovy HttpBuilder.
based on info from sonatype, and a few other sources.
This works with http-builder version 0.7.2 (not with earlier versions)
And also needs an extra dependency: 'org.apache.httpcomponents:httpmime:4.2.1'
The example also uses basic auth against nexus.
import groovyx.net.http.Method
import groovyx.net.http.ContentType;
import org.apache.http.HttpRequest
import org.apache.http.HttpRequestInterceptor
import org.apache.http.entity.mime.MultipartEntity
import org.apache.http.entity.mime.content.FileBody
import org.apache.http.entity.mime.content.StringBody
import org.apache.http.protocol.HttpContext
import groovyx.net.http.HttpResponseException;
class NexusUpload {
def uploadArtifact(Map artifact, File fileToUpload, String user, String password) {
def path = "/service/local/artifact/maven/content"
HTTPBuilder http = new HTTPBuilder("http://my-nexus.org/")
String basicAuthString = "Basic " + "$user:$password".bytes.encodeBase64().toString()
http.client.addRequestInterceptor(new HttpRequestInterceptor() {
void process(HttpRequest httpRequest, HttpContext httpContext) {
httpRequest.addHeader('Authorization', basicAuthString)
}
})
try {
http.request(Method.POST, ContentType.ANY) { req ->
uri.path = path
MultipartEntity entity = new MultipartEntity()
entity.addPart("hasPom", new StringBody("false"))
entity.addPart("file", new FileBody(fileToUpload))
entity.addPart("a", new StringBody("my-artifact-id"))
entity.addPart("g", new StringBody("my-group-id"))
entity.addPart("r", new StringBody("my-repository"))
entity.addPart("v", new StringBody("my-version"))
req.entity = entity
response.success = { resp, reader ->
if(resp.status == 201) {
println "success!"
}
}
}
} catch (HttpResponseException e) {
e.printStackTrace()
}
}
}
`
Ivy is an open source library, so, one approach would be to call the classes directly. The problem with that approach is that there are few examples on how to invoke ivy programmatically.
Since groovy has excellent support for generating XML, I favour the slightly dumber approach of creating the files I understand as an ivy user.
The following example is designed to publish files into Nexus generating both the ivy and ivysettings files:
import groovy.xml.NamespaceBuilder
import groovy.xml.MarkupBuilder
// Methods
// =======
def generateIvyFile(String fileName) {
def file = new File(fileName)
file.withWriter { writer ->
xml = new MarkupBuilder(writer)
xml."ivy-module"(version:"2.0") {
info(organisation:"org.dummy", module:"dummy")
publications() {
artifact(name:"dummy", type:"pom")
artifact(name:"dummy", type:"jar")
}
}
}
return file
}
def generateSettingsFile(String fileName) {
def file = new File(fileName)
file.withWriter { writer ->
xml = new MarkupBuilder(writer)
xml.ivysettings() {
settings(defaultResolver:"central")
credentials(host:"myrepo.com" ,realm:"Sonatype Nexus Repository Manager", username:"deployment", passwd:"deployment123")
resolvers() {
ibiblio(name:"central", m2compatible:true)
ibiblio(name:"myrepo", root:"http://myrepo.com/nexus", m2compatible:true)
}
}
}
return file
}
// Main program
// ============
def ant = new AntBuilder()
def ivy = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.ivy.ant')
generateSettingsFile("ivysettings.xml").deleteOnExit()
generateIvyFile("ivy.xml").deleteOnExit()
ivy.resolve()
ivy.publish(resolver:"myrepo", pubrevision:"1.0", publishivy:false) {
artifacts(pattern:"build/poms/[artifact].[ext]")
artifacts(pattern:"build/jars/[artifact].[ext]")
}
Notes:
More complex? Perhaps... however, if you're not generating the ivy file (using it to manage your dependencies) you can easily call the makepom task to generate the Maven POM files prior to upload into Nexus.
The REST APIs for Nexus work fine. I find them a little cryptic and of course a solution that uses them cannot support more than one repository manager (Nexus is not the only repository manager technology available).
The "deleteOnExit" File method call ensures the working files are cleaned up properly.
This is my first Meteor application, I'm really excited to try to learn the framework, so I just built an internal website that will manage a bunch of command line processes. Many of these command line processes take 10-20 minutes to execute, so I was hoping I could deliver feedback to the user during execution, such as piping the stdout back to the user as the process executed. Right now I'm doing this:
var require __meteor_bootstrap__.require
var sys = require('sys')
var exec = require('child_process').exec;
Meteor.methods({
foo: function(job_id) {
var select = { _id: job_id };
var execCommand = "dir /s"; // or whatever it is I'm doing
exec(execCommand, function(error, stdout, stderr) {
Fiber (function() {
Jobs.update(select, {$set: { logs: stdout }});
}).run();
})
}
});
This works fine, and when the job completes I see the log, but I was wondering if there was a better way I could do it so that as results are available I can start sending them. Any advise is welcome.
I would append the output line by line using the MongoDB $push operator instead of resetting the content of "logs" every time. That will save you some bandwidth I guess.
But apart from that, exec does not call your function regulary. Take a look at the "node.js execute system command synchronously question for a workaround.