rich-harris / degit Goto Github PK
View Code? Open in Web Editor NEWStraightforward project scaffolding
License: MIT License
Straightforward project scaffolding
License: MIT License
The 1st paragraph in the README says
"and download the associated tar file to ~/.degit/some-user/some-repo/commithash.tar.gz if it doesn't already exist locally"
but the behaviour I see is a bunch of local files, not the zip as this implies
I think that adding the ability to clone a repo into a specific location will be a useful feature that is missing right now.
According to https://en.wikipedia.org/wiki/Comparison_of_source_code_hosting_facilities#Version_control_systems , there are a bunch of git services that degit might want to support:
Splitting off from the conversation at #16:
@melniker says:
I was planning on working on non-github support [...], and my plan included a config json file that gave the characteristics of the servers. I was going to pre-populate it for github/gitlab/bitbucket but it could then be easily extendable for other servers. It would specify every property you'd need, including URI format & location of the tarball.
This way, degit would be easily extendable not only for public git servers (which could be put into debit/master via PR) but also for private instances inside a big corporation, e.g.
Could also of course take these config settings via cli parameters.
Thoughts?
I, on the other hand, would prefer something of the form:
gitlab-https://my-own-gitlab-server.local/my-user/-my-repo.git
Maybe also parsing the repo URL and checking if the substrings gitlab
or bitbucket
(and so on) are in there. Personally I'd prefer as little configuration as possible.
When I first tried adding --verbose
, I tried to put it as the first parameter. This gives an error:
degit --verbose sveltejs/sapper-template my-app
/home/[obfuscated]/.nvm/versions/node/v8.9.1/lib/node_modules/degit/index.js:237
throw new DegitError(`could not parse ${src}`, {
^
Error: could not parse my-app
at parse (/home/[obfuscated]/.nvm/versions/node/v8.9.1/lib/node_modules/degit/index.js:237:9)
I subsequently realised I should put it at the end. But it would be nice for the above ordering to work too?
Under the new Actions section, this sentence isn't quite right:
This will clone the contents of
user/another-repo
on top of the existing repo.
It should read as something like this:
This will clone the contents of
user/another-repo
into the current directory. If duplicate files exist, the one in the current directory will overwrite the one in any cloned-down repos. This allows you to easily customize the final state of your scaffold when combining multiple repos.
Last sentence could also be cut if the intent of this behavior is clear enough.
Would be cool if running degit
without arguments took you to an interactive mode where you could see which repos were available locally, and which refs thereof. And maybe let you select from that list by typing with fuzzy matching etc.
I am trying to use the JS interface, but I get a failure without any error.
const emitter = degit(args.repo, {
cache: false,
force: true,
verbose: true,
});
In this case args.repo
is a valid user/repo
path for GitHub. I can validate it works by running the CLI degit user/repo
without any issue.
Adding the following results in zero messaging being displayed.
emitter.on('info', (info: DegitMessage) => {
console.log(info.message);
});
emitter.on('warn', (info: DegitMessage) => {
console.log(info.message);
});
Any code below the emitter seems to work, so it's not killing the file processing, it just does nothing.
DegitMessage is just a
ts
interface I made.
When outputting the emitter to the console, I get the following -
Degit {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
src: 'user/repo',
cache: false,
force: true,
verbose: true,
proxy: undefined,
repo:
{ site: 'github',
user: 'user',
name: 'repo',
ref: 'master',
url: 'https://github.com/user/repo',
ssh: '[email protected]:user/repo',
subdir: undefined,
mode: 'tar' },
mode: 'tar',
_hasStashed: false,
directiveActions:
{ clone: [AsyncFunction: clone],
remove: [Function: bound remove] } }
Hey Rich,
Was wondering if theres any way to make degit work with a lerna monorepo (say a collection of templates) without some crazy action logic being implemented. Something like degit rich-harris/monorepo/packages/template
. Thanks!
By using ssh protocol for the getRefs function, the user is forced to set up ssh keys in GitHub, if s/he doesn't already have it set up. Seems unnecessary, since the .tar.gz pull is explicitly via HTTP protocol.
Let me know if I'm totally off base (git noob / github contributor noob ... just trying to help :))!
Hi guys,
First of all, I just stumbled upon this project and got curious to setup. when i started to set this up and run a debug session in vscode. I get wierd errors. Will you be able to help?
Error Console
C:\Program Files\nodejs\node.exe --experimental-modules --inspect-brk=21392 src\bin.js
Debugger listening on ws://127.0.0.1:21392/9a801ff3-7b13-477d-b833-e713a72667d5
For help, see: https://nodejs.org/en/docs/inspector
Debugger attached.
(node:4660) ExperimentalWarning: The ESM module loader is experimental.
SyntaxError: Unexpected identifier
Software used
Version: 1.40.2 (system setup)
Commit: f359dd69833dd8800b54d458f6d37ab7c78df520
Date: 2019-11-25T14:54:45.096Z
Electron: 6.1.5
Chrome: 76.0.3809.146
Node.js: 12.4.0
NPM : 6.9.0
V8: 7.6.303.31-electron.0
OS: Windows_NT x64 10.0.18363
launch.json
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"runtimeArgs": ["--experimental-modules"],
"program": "${workspaceFolder}\\src\\bin.js"
}
]
much quicker than using git clone, because you're not downloading the entire git history.
How does degit
differ from a shallow clone?
Might be worth mentioning in the README.
First and foremost, thank you so much for this awesome tool. Saves me so much time scaffolding new repos everyday.
While attempting to use the new actions feature, I wanted to have a degit.json
in the same repository to be able to specify actions to be executed after clone.
For example, In this repo, https://github.com/osdevisnot/degit-demo -- I have a degit.json
file as:
[
{
"action": "remove",
"files": ["README.md", "degit.json"]
}
]
and I was expecting this will remove specific files when one clones this template with command like this:
degit osdevisnot/degit-demo my-app
However, this errors out with message:
! action wants to remove README.md but it does not exist
On further investigation, it seems when actions are specified, we are attempting to stash files before executing command in destination folder here:
https://github.com/Rich-Harris/degit/blob/master/src/index.js#L121
This seems misleading, the actions are being executed in dest
directory, which was stashed right before and does not exist when executing this command.
What solution approach should I follow to achieve this use case?
I'm trying to clone a repo into the current directory I'm on, and I keep getting an error, event when the directory is empty.
This is the error I'm getting:
! destination directory is not empty, aborting. Use --force to override
@Rich-Harris I'm not mistaken, it's a bug, right?
! could not fetch remote https://github.com/sveltejs/template
! could not find commit hash for master
Environment info:
Degit v2.8.0
Node.js v10.x
Windows 10
Output after running degit
in powershell:
(node:20120) UnhandledPromiseRejectionWarning: TypeError: sync(...).map(...).flat is not a function
at main (C:\Users\yogib\scoop\persist\nvm\nodejs\v10.18.1\node_modules\degit\dist\bin.js:5551:5)
at Object.<anonymous> (C:\Users\yogib\scoop\persist\nvm\nodejs\v10.18.1\node_modules\degit\dist\bin.js:5627:1)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object.<anonymous> (C:\Users\yogib\scoop\persist\nvm\nodejs\v10.18.1\node_modules\degit\bin.js:2:1)
(node:20120) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function
without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:20120) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I think it's a compatability issue with node@10, and can be solved by either changing the code, or starting to use babel for backwards compatibility.
I, personally think that it's okay if we only targeted node@lts and node@latest.
Getting the following error when attempting to use degit (even trying degit -h
):
.../lib/node_modules/degit/index.js:89
async clone(dest) {
^^^^^
SyntaxError: Unexpected identifier
Is this supposed to be compiled? Or is node 6 not supported?
Node v6.11.3 npm v3.10.10
It would be nice if the ability to read a degit.json
file were available from the JS API too. I took a quick stab at it here with a test in there as well: https://github.com/Rich-Harris/degit/compare/master...mhkeller:actions-js-api?expand=1
You call it like this, similar to .clone
degit().doActions([
{action: 'clone', src: 'mhkeller/degit-test-repo-compose'}
], '.tmp/test-repo')
A few things:
.doActions
for now but open to other suggestions..clone
as possible but maybe the arguments should be different.degit
?Haven't looked into what this would entail
Hi Rich! Many of the code bases I work on w/ others are renaming master
to main
. Is there an easy way to set the default branch w/ degit
to something that isn't master
within a project?
I personally couldn't care less about this, but will gladly accept a PR from anyone who does care.
I followed the getting started guide (https://sapper.svelte.technology/guide#getting-started) but running degit
returns an error.
After running npm install -g degit
as per the above guide, I ran degit sveltejs/sapper-template my-app
and get the following error.
kevin.heard ~/git $ degit sveltejs/sapper-template my-app
module.js:549
throw err;
^
Error: Cannot find module 'sander'
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/Users/kevin.heard/.nvm/versions/node/v8.10.0/lib/node_modules/degit/index.js:11:14)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
I noticed that sander
is in devDependencies
, which it looks like it should be in dependencies
?
Hey there—I'm trying to get started with Svelte and running:
Environment:
Running:
degit sveltejs/template-webpack
... gives me:
! could not find commit hash for master
Double checking that the user/repo
is correct, I'm not really sure why it can't find the hash. I tried it with a couple other repos out there and no-go.
Any ideas?
I'm using the one liner in my electron (2) app:
degit('Rich-Harris/degit-test-repo', { force: true }).clone('/tmp/test-repo')
which throws aforementioned error.
Hi Rich. I'm following the Sapper Getting Started Guide and running: degit sveltejs/sapper-template my-app
.
But I'm here on the office network behind a proxy - and the command hangs and eventually says "could not download".
I have my proxy settings set OK in my environment variables (http_proxy
, https_proxy
). I've checked that in the same terminal, I'm able to download the same URL OK using wget
.
Would you be OK with adding the ability to deal with proxies?
I've previously done this using something like this:
import httpsProxyAgent from 'https-proxy-agent';
const httpsProxy = process.env.https_proxy;
let fetchOptions = null;
if (httpsProxy) {
// Log: 'Using proxy server': httpsProxy
fetchOptions = {agent: new httpsProxyAgent(httpsProxy)};
}
fetch(fooBarURL, fetchOptions)
If you'd be happy with the same approach - using https-proxy-agent? - I could write a PR if you like?
If we can't fetch refs because we're offline, it should still be possible to use a cached archive. Right now they're only stored by commit hash which is unhelpful — we could store some metadata alongside the tar files, indicating that (for example) 1234abcd is the latest master
.
This is what I'm trying to do:
$ which git
/usr/bin/git
$ git --version
git version 2.17.1
$ git remote -v
origin [email protected]:org1/path/path2/path3/wsrepsal.git (fetch)
origin [email protected]:org1/path/path2/path3/wsrepsal.git (push)
$ git tag
v1.0.0
v1.0.1
---
on another folder I try to...
$ npx degit [email protected]:org1/path/path2/path3/wsrepsal#v1.0.0 wsrepsal
npx: installed 33 in 1.534s
Username for 'https://gitlab.com': xxxxx
Password for 'https://[email protected]':
! could not find commit hash for master
So, I have git installed and available, I have a gitlab repo with a couple of tags, then I go to another folder and try to degit that repo with tag... It seems to look for a commit hash for master....
Am I missing anything???
Otherwise, it's not clear if it's actually cloning the repo or hangs.
$ npx degit kriasoft/nodejs-api-starter
Hi,
First of all, thanks for the awesome tool.
But while reading the documentation there are no cues about where degit.json needs to be placed.
For my surprise (reading the code), it needs to be set at the destination folder and not at src ('.').
This is a bit counter intuitive, since I don't have control of some repos I want to "clone" with degit and even if first create the destination folder with degit.json file it won't work it will be cleaned after the extraction.
My suggestion it is to add: --config 'path' to command line or set as default '.' location and also clarify it at the docs.
Cheers,
Pedro.
Via Twitter. We could support this...
import degit from 'degit';
degit(src, dest, opts).then(() => {
// ...
});
...instead of this:
import child_process from 'child_process';
child_process.exec(`degit ${src} ${dest}`, (err, stdout, stderr) => {
// ...
});
Would require some rejigging. degit
would need to take a set of options (rather than treating command line args as globals, effectively) and would probably need to return an event emitter for the sake of logging.
If a repo has a .degit.yml file, we could put a postinstall script in there that automated setup tasks like npm install
. For security reasons, the script should be shown and the user should be prompted for confirmation (typing y
, not just hitting Enter) before it happens.
We could also show a success message defined in the YAML file.
success: >
Congratulations! Now install dependencies with `npm install`, then run `npm run dev` to
start a development server and open http://localhost:5000 to see your app. Visit
https://example.com for more information.
postinstall: npm install
Right now GitHub is hard-coded, which is probably fine in 99% of cases. Would accept a PR that enabled this sort of thing:
degit https://gitlab.com/some-user/some-repo
degit gitlab:some-user/some-repo
(Second example subject to bikeshedding.)
2.1.0 brings the concept of actions — see #28.
So far we have clone
and remove
. I can think of a few others that might be useful:
rename
— for moving files out of the way to prevent them being clobbered by clonereplace
— for replacing placeholder stuff in particular files, such as this TODO. Would need to come after a...prompt
— get some user input. terkelg/prompts has some nice conventions we could adopt.So you could do this sort of thing:
[
{
"action": "prompt",
"questions": [
{ "type": "text", "name": "name", "message": "What is the project name?" }
]
},
{
"action": "replace",
"delimiters": ["<<", ">>"],
"values": ["name"],
"files": ["package.json"]
}
]
then if you had a package.json like
{
"name": "<<name>>",
...
}
it would get filled in. Not fully baked (maybe the replace
action should run in the context of the prompt?) but you get the idea. cc @mhkeller if you have thoughts
I was unable to install or run this tool without node 8 due to use of async
:
Line 36 in 84b215c
Shouldn't engine
should be specified in package.json
?
I want to add the ability to use self-hosted servers. I want to realize this through agrument --trusted / -t, such as:
degit [email protected]:user/repo#dev my-app -t my.gitlab.io
Do you need it in the master or is it better to make my fork and keep it?
Thank you!
Hi!
I have tried using degit, but no matter what repo I try to clone it throws a ! could not download ...
error. I forked and cloned the repo was able to pinpoint the error to this line
Line 129 in 7531fbe
I've added a console.log right above the line and logged the caught error which gave me this output:
I've went further and located that it actually errors here on line 69:
Lines 66 to 69 in 7531fbe
I think it is worth mentioning that I use volta for managing node versions, that may have an effect on permissions.
I'd be happy to help solve this, submit a PR or something, but at this point I don't know which direction I should go.
Hey, thank you for your work but I want to ask what is the difference between your project and using git clone --depth 1
which will cause getting only the last commit
And for the branches I believe git has a solution for that too using git clone -b <branch> <remote_repo>
Degit should be using $XDG_CACHE_HOME/degit
instead of ~/.degit
to store downloaded repositories.
This keeps users' home directories clean of dotfiles. It is being widely adopted by Linux/BSD applications.
See here for more info.
Some repo does not have the master branch (like https://github.com/npm/hosted-git-info).
I've got a project that's scaffolded with Degit where I'd like to remove all .md
files in the .github
folder, but not the .yml
files (workflow files) but globbing (.github/**/*.md
) doesn't work. I'm asking if it's possible to support that!
Thank you!
I'm looking for a tool to keep initial scaffolding up to date.
Like say some linting rules were part of an initial scaffolding. Then we updated the rules in the source repo. Now how do we bring the updated rules to the project that was scaffolded using our source repo?
This is something I'm really interested in and might be able to find time to work on it if you have some ideas?
I found degit to be really useful for copying example code from tutorials without the overhead of keeping the git history. Almost all of the time, the dest
argument is the same as the repository name, and it would be convenient IMO to have an argument like -r
to expedite this.
Not sure if this is too esoteric of a feature though.
I found some features missing from the clone
action, one being the ability to clone specific files, which would essentially mean to clone the repo and delete all the files not "chosen".
On Fedora 31, standard install of npm install -g degit
nodejs v12.15.0
[vagrant@localhost ~]$ which degit
/usr/local/bin/degit
[vagrant@localhost ~]$ ls -l /usr/local/bin/degit
lrwxrwxrwx. 1 root root 32 Feb 19 15:03 /usr/local/bin/degit -> ../lib/node_modules/degit/bin.js
[vagrant@localhost ~]$ degit --help
(node:2423) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '/usr/local/lib/node_modules/degit/dist/help.md'
at Object.openSync (fs.js:440:3)
at Object.readFileSync (fs.js:342:35)
at main (/usr/local/lib/node_modules/degit/dist/bin.js:5514:5)
at Object.<anonymous> (/usr/local/lib/node_modules/degit/dist/bin.js:5627:1)
at Module._compile (internal/modules/cjs/loader.js:955:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
at Module.load (internal/modules/cjs/loader.js:811:32)
at Function.Module._load (internal/modules/cjs/loader.js:723:14)
at Module.require (internal/modules/cjs/loader.js:848:19)
at require (internal/modules/cjs/helpers.js:74:18)
(node:2423) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:2423) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Version 2.6.0 doesn't have the error.
I think a cleanup option is missing to delete the dist
directory before publishing.
I see copies of the same file with different names in dist
.
For example, compare these two files:
https://cdn.jsdelivr.net/npm/[email protected]/dist/index-26d8486e.js
https://cdn.jsdelivr.net/npm/[email protected]/dist/index-386dbe4f.js
Take a peek at the size of each version:
https://packagephobia.com/result?p=degit
cc @Rich-Harris
Was trying out degit and got this error...
node v8.4.0
degit v1.2.2
osx v10.12.4
npm install -g degit
degit svelte/template
Error: [!] could not find commit hash for master
Hi guys,
When trying to create a template project with:
degit sveltejs/template my-template-project
The following error is raised in the command line:
! zlib: Cannot read property 'length' of null
Windows 7 Professional
Command Line with/without Administrator rights
The path where I'm trying to initialize the project is not restricted in any way.
What it can be?
Update:
I think it is something related to Windows 7 or my machine. I've tested it on a Windows 10 and it is working fine. Can you please close this issue as probably there is no one to use Windows 7 anymore :P.
Best!
Razvan
Gists are just git repos under the covers, but degit
doesn't seem to understand their git repo URLs.
> degit https://gist.github.com/5e392a94903989cdc5fc786c2bc585eb.git test
[!] could not parse https://gist.github.com/5e392a94903989cdc5fc786c2bc585eb.git
Am I doing this wrong? It seems like it should work, at least in theory.
I did a little digging in order to test if the Remove
action works when the stashing and un-stashing is disabled, and it does.
What's the purpose of the file stashing?
The code is right here:
const directives = tryRequire(path.resolve(dest, degitConfigName), {clearCache: true}) || false;
if (directives) {
stashFiles(dir, dest);
for (const d of directives) {
// TODO, can this be a loop with an index to pass for better error messages?
await this.directiveActions[d.action](dest, d);
}
unstashFiles(dir, dest);
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.