CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-degit

Straightforward project scaffolding tool that clones git repositories without history

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

cloning.mddocs/

Repository Cloning

Core repository cloning functionality supporting multiple git platforms and cloning modes with comprehensive error handling and event system.

Capabilities

Degit Factory Function

Creates a new Degit instance for cloning operations.

/**
 * Creates a new Degit instance for cloning operations
 * @param src - Repository source (user/repo, URL, or platform:user/repo format)
 * @param opts - Configuration options
 * @returns DegitInstance extending EventEmitter
 */
function degit(src, opts): DegitInstance;

Usage Examples:

import degit from "degit";

// Basic usage
const emitter = degit("Rich-Harris/degit");

// With options
const emitter = degit("user/repo#v1.0.0", {
  cache: false,
  force: true,
  verbose: true,
  mode: "tar"
});

// Different repository formats
const githubRepo = degit("user/repo");
const gitlabRepo = degit("gitlab:user/repo");
const bitbucketRepo = degit("bitbucket:user/repo");
const sourcehutRepo = degit("git.sr.ht/user/repo");
const httpsRepo = degit("https://github.com/user/repo");
const sshRepo = degit("git@github.com:user/repo");

Degit Class

Main class for handling repository cloning operations with event-driven architecture.

/**
 * Main class for handling repository cloning operations
 * Extends EventEmitter for progress and error reporting
 */
interface DegitInstance extends EventEmitter {
  constructor(src: string, opts?: DegitOptions);
  
  /** Clone repository to destination directory */
  clone(dest: string): Promise<void>;
  
  /** Remove files/directories as part of degit actions */
  remove(dir: string, dest: string, action: RemoveAction): void;
}

interface DegitOptions {
  /** Use cached version if available */
  cache?: boolean;
  /** Allow cloning to non-empty directory */
  force?: boolean;
  /** Enable verbose logging */
  verbose?: boolean;
  /** Force specific cloning mode */
  mode?: "tar" | "git";
}

Clone Method

Clones the repository to the specified destination directory.

/**
 * Clones the repository to the specified destination directory
 * @param dest - Destination directory path (relative or absolute)
 * @returns Promise that resolves when cloning is complete
 * @throws DegitError for various error conditions
 */
async clone(dest: string): Promise<void>;

Usage Examples:

import degit from "degit";

// Clone to current directory
const emitter = degit("user/repo");
await emitter.clone(".");

// Clone to specific directory
await emitter.clone("./my-project");

// Clone with event handling
emitter.on("info", info => {
  console.log(`INFO: ${info.message}`);
});

emitter.on("warn", warn => {
  console.warn(`WARN: ${warn.message}`);
});

try {
  await emitter.clone("./project");
  console.log("Clone completed successfully");
} catch (error) {
  console.error("Clone failed:", error.message);
}

Remove Method

Removes specified files or directories as part of degit actions defined in degit.json.

/**
 * Removes specified files or directories as part of degit actions
 * @param dir - Source directory path
 * @param dest - Destination directory path
 * @param action - Remove action configuration
 */
remove(dir: string, dest: string, action: RemoveAction): void;

interface RemoveAction {
  action: "remove";
  files: string | string[];
}

Event System

The DegitInstance emits events during the cloning process for progress tracking and error handling.

Info Events

interface InfoEvent {
  code: string;
  message: string;
  repo?: RepoInfo;
  dest?: string;
}

// Event codes include:
// - "SUCCESS": Clone completed successfully
// - "DEST_NOT_EMPTY": Destination directory not empty (with force option)
// - "DEST_IS_EMPTY": Destination directory is empty
// - "USING_CACHE": Using cached commit hash
// - "FOUND_MATCH": Found matching commit hash
// - "FILE_EXISTS": File already exists locally
// - "PROXY": Using proxy for download
// - "DOWNLOADING": Downloading tar file
// - "EXTRACTING": Extracting tar file
// - "REMOVED": Files removed via degit action

Warn Events

interface WarnEvent {
  code: string;
  message: string;
}

// Event codes include:
// - "FILE_DOES_NOT_EXIST": Action wants to remove non-existent file
// - Various network and git-related warnings

Event Handling Examples:

import degit from "degit";

const emitter = degit("user/repo");

// Handle info events
emitter.on("info", (event) => {
  switch (event.code) {
    case "SUCCESS":
      console.log("✅ Clone completed successfully");
      break;
    case "DOWNLOADING":
      console.log("📥 Downloading repository...");
      break;
    case "EXTRACTING":
      console.log("📂 Extracting files...");
      break;
    default:
      console.log(`ℹ️  ${event.message}`);
  }
});

// Handle warnings
emitter.on("warn", (event) => {
  console.warn(`⚠️  ${event.message}`);
});

Error Handling

Degit uses a custom error class for specific error conditions.

class DegitError extends Error {
  constructor(message: string, opts: ErrorOptions);
}

interface ErrorOptions {
  code: string;
  [key: string]: any;
}

// Common error codes:
// - "DEST_NOT_EMPTY": Destination directory not empty (without force)
// - "BAD_SRC": Could not parse repository source
// - "UNSUPPORTED_HOST": Repository host not supported
// - "MISSING_REF": Could not find specified branch/tag/commit
// - "COULD_NOT_DOWNLOAD": Failed to download repository
// - "COULD_NOT_FETCH": Could not fetch git references
// - "BAD_REF": Could not parse git reference

Repository Source Parsing

Degit supports various repository source formats:

interface RepoInfo {
  site: string;        // "github", "gitlab", "bitbucket", "git.sr.ht"
  user: string;        // Repository owner/user
  name: string;        // Repository name
  ref: string;         // Branch, tag, or commit hash (defaults to "HEAD")
  url: string;         // HTTPS URL for repository
  ssh: string;         // SSH URL for repository
  subdir?: string;     // Subdirectory path if specified
  mode: "tar" | "git"; // Cloning mode
}

Supported Source Formats:

// Basic formats
"user/repo"                          // GitHub, latest commit
"user/repo#branch"                   // Specific branch
"user/repo#v1.2.3"                   // Specific tag
"user/repo#abcd1234"                 // Specific commit

// Platform-specific formats
"github:user/repo"                   // GitHub explicit
"gitlab:user/repo"                   // GitLab
"bitbucket:user/repo"               // BitBucket
"git.sr.ht/user/repo"               // Sourcehut

// URL formats
"https://github.com/user/repo"       // HTTPS URL
"https://github.com/user/repo.git"   // HTTPS with .git
"git@github.com:user/repo"          // SSH URL

// Subdirectory support
"user/repo/path/to/subdir"          // Clone only subdirectory
"user/repo/path/to/subdir#branch"   // Subdirectory with branch

Cloning Modes

Tar Mode (Default)

Downloads repository as tar archive, faster and more efficient.

  • Downloads tar file of specific commit
  • Caches downloaded files locally
  • Supports HTTPS proxy
  • Default mode for supported platforms

Git Mode

Uses traditional git clone via SSH, required for private repositories.

  • Clones entire repository via SSH
  • Removes .git directory after clone
  • Required for private repositories
  • Slower than tar mode due to full git history download

Mode Selection Examples:

// Force tar mode (default)
const emitter = degit("user/repo", { mode: "tar" });

// Force git mode (for private repos)
const emitter = degit("user/repo", { mode: "git" });

// Auto-detection based on repository URL
const emitter = degit("git@github.com:user/private-repo"); // Uses git mode

Install with Tessl CLI

npx tessl i tessl/npm-degit

docs

actions.md

cli.md

cloning.md

index.md

tile.json