create-defuss
Version:
Checks out git projects from sub-directories. Originally for jump-starting defuss projects from templates.
8 lines (6 loc) • 3.33 kB
JavaScript
var v=Object.defineProperty;var f=(e,s)=>v(e,"name",{value:s,configurable:!0});var h=require("node:child_process"),r=require("node:path"),t=require("node:fs"),R=require("node:os");const k=/^(https:\/\/(?:github|gitlab|bitbucket)\.com)\/([^\/]+)\/([^\/]+)\/(?:tree|src)\/([^\/]+)\/(.+)$/,S=f((e,s,a=k)=>{try{const i=e.match(a);if(!i)throw new Error("Invalid URL format. Use a subdirectory URL (https) from GitHub, GitLab, or Bitbucket.");const[,c,n,l,u,E]=i;[n,l,u].forEach(m=>{if(!/^[\w\-]+$/.test(m))throw new Error(`Invalid characters in input: ${m}`)});const p=r.normalize(E);if(r.isAbsolute(p)||p.startsWith("..")||p.includes(`${r.sep}..${r.sep}`))throw new Error("Invalid subdirectory path.");const d=p,g=s||r.basename(d),y=r.resolve(process.cwd(),g);if(t.existsSync(y))throw new Error(`Destination folder "${g}" already exists.`);t.mkdirSync(y,{recursive:!0});const o=t.mkdtempSync(r.join(R.tmpdir(),"sparse-checkout-"));if(console.log("Cloning repository with sparse checkout into temporary directory..."),h.spawnSync("git",["clone","--no-checkout",`${c}/${n}/${l}.git`,o],{stdio:"inherit"}).status!==0)throw new Error("Git clone failed.");const w=r.resolve(o,d);if(!w.startsWith(o+r.sep)&&w!==o)throw new Error("Subdirectory path traversal detected.");if(console.log("Initializing sparse-checkout..."),h.spawnSync("git",["-C",o,"sparse-checkout","init"],{stdio:"inherit"}).status!==0)throw new Error("Git sparse-checkout init failed.");if(console.log(`Setting sparse-checkout to subdirectory: ${d}`),h.spawnSync("git",["-C",o,"sparse-checkout","set",d],{stdio:"inherit"}).status!==0)throw new Error("Git sparse-checkout set failed.");if(console.log(`Checking out branch: ${u}...`),h.spawnSync("git",["-C",o,"checkout",u],{stdio:"inherit"}).status!==0)throw new Error("Git checkout failed.");if(!t.existsSync(w))throw new Error(`Subdirectory "${d}" does not exist in the repository.`);if(console.log("Copying files to the destination directory..."),b(w,y),console.log("Cleaning up temporary directory..."),t.rmSync(o,{recursive:!0,force:!0}),console.log("Initializing a new git repository..."),h.spawnSync("git",["init"],{cwd:y,stdio:"inherit"}).status!==0)throw new Error("Initializing new git repository failed.");console.log("\u{1F389} All done! Your new project has been set up!"),console.log(`
To get started, run the following commands:
cd ${g}
`)}catch(i){console.error("Error during sparse checkout:",i.message),process.exit(1)}},"performSparseCheckout");function b(e,s){if(!t.existsSync(e))throw new Error(`Source directory "${e}" does not exist.`);const a=t.readdirSync(e);for(const i of a){const c=r.join(e,i),n=r.join(s,i),l=t.lstatSync(c);if(l.isDirectory())t.mkdirSync(n,{recursive:!0}),b(c,n);else if(l.isSymbolicLink()){const u=t.readlinkSync(c);t.symlinkSync(u,n)}else t.copyFileSync(c,n)}}f(b,"copyDirectoryContents");const $=f(async()=>{const e=process.argv.slice(2);(e.length<1||e.length>2)&&(console.error(`Usage: create-defuss <repo-url> [destination-folder]
Example: create-defuss https://github.com/kyr0/defuss/tree/main/examples/with-astro-ts ./my-new-project`),process.exit(1));const s=e[0],a=e[1];S(s,a)},"main");$().catch(e=>{console.error("Unexpected error:",e),process.exit(1)}),exports.defaultScmHostPattern=k,exports.performSparseCheckout=S;
//# sourceMappingURL=cli.cjs.map
;