diff --git a/compiled_starters/c/.codecrafters/compile.sh b/compiled_starters/c/.codecrafters/compile.sh new file mode 100755 index 0000000..4ef5842 --- /dev/null +++ b/compiled_starters/c/.codecrafters/compile.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +gcc -o /tmp/codecrafters-build-git-c app/*.c diff --git a/compiled_starters/c/.codecrafters/run.sh b/compiled_starters/c/.codecrafters/run.sh new file mode 100755 index 0000000..1c93056 --- /dev/null +++ b/compiled_starters/c/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec /tmp/codecrafters-build-git-c "$@" diff --git a/compiled_starters/c/.gitattributes b/compiled_starters/c/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/compiled_starters/c/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/compiled_starters/c/.gitignore b/compiled_starters/c/.gitignore new file mode 100644 index 0000000..c6127b3 --- /dev/null +++ b/compiled_starters/c/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/compiled_starters/c/README.md b/compiled_starters/c/README.md new file mode 100644 index 0000000..3ff2edc --- /dev/null +++ b/compiled_starters/c/README.md @@ -0,0 +1,59 @@ +![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/git.png) + +This is a starting point for C solutions to the +["Build Your Own Git" Challenge](https://codecrafters.io/challenges/git). + +In this challenge, you'll build a small Git implementation that's capable of +initializing a repository, creating commits and cloning a public repository. +Along the way we'll learn about the `.git` directory, Git objects (blobs, +commits, trees etc.), Git's transfer protocols and more. + +**Note**: If you're viewing this repo on GitHub, head over to +[codecrafters.io](https://codecrafters.io) to try the challenge. + +# Passing the first stage + +The entry point for your Git implementation is in `app/main.c`. Study and +uncomment the relevant code, and push your changes to pass the first stage: + +```sh +git commit -am "pass 1st stage" # any msg +git push origin master +``` + +That's all! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `gcc` installed locally +1. Run `./your_program.sh` to run your Git implementation, which is implemented + in `app/main.c`. +1. Commit your changes and run `git push origin master` to submit your solution + to CodeCrafters. Test output will be streamed to your terminal. + +# Testing locally + +The `your_program.sh` script is expected to operate on the `.git` folder inside +the current working directory. If you're running this inside the root of this +repository, you might end up accidentally damaging your repository's `.git` +folder. + +We suggest executing `your_program.sh` in a different folder when testing +locally. For example: + +```sh +mkdir -p /tmp/testing && cd /tmp/testing +/path/to/your/repo/your_program.sh init +``` + +To make this easier to type out, you could add a +[shell alias](https://shapeshed.com/unix-alias/): + +```sh +alias mygit=/path/to/your/repo/your_program.sh + +mkdir -p /tmp/testing && cd /tmp/testing +mygit init +``` diff --git a/compiled_starters/c/app/main.c b/compiled_starters/c/app/main.c new file mode 100644 index 0000000..8313113 --- /dev/null +++ b/compiled_starters/c/app/main.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + // Disable output buffering + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + if (argc < 2) { + fprintf(stderr, "Usage: ./your_program.sh []\n"); + return 1; + } + + const char* command = argv[1]; + + if (strcmp(command, "init") == 0) { + // You can use print statements as follows for debugging, they'll be visible when running tests. + fprintf(stderr, "Logs from your program will appear here!\n"); + + // Uncomment this block to pass the first stage + // if (mkdir(".git", 0755) == -1 || + // mkdir(".git/objects", 0755) == -1 || + // mkdir(".git/refs", 0755) == -1) { + // fprintf(stderr, "Failed to create directories: %s\n", strerror(errno)); + // return 1; + // } + // + // FILE* headFile = fopen(".git/HEAD", "w"); + // if (headFile == NULL) { + // fprintf(stderr, "Failed to create .git/HEAD file: %s\n", strerror(errno)); + // return 1; + // } + // fprintf(headFile, "ref: refs/heads/main\n"); + // fclose(headFile); + // + // printf("Initialized git directory\n"); + } else { + fprintf(stderr, "Unknown command %s\n", command); + return 1; + } + + return 0; +} diff --git a/compiled_starters/c/codecrafters.yml b/compiled_starters/c/codecrafters.yml new file mode 100644 index 0000000..0a06ac0 --- /dev/null +++ b/compiled_starters/c/codecrafters.yml @@ -0,0 +1,11 @@ +# Set this to true if you want debug logs. +# +# These can be VERY verbose, so we suggest turning them off +# unless you really need them. +debug: false + +# Use this to change the C version used to run your code +# on Codecrafters. +# +# Available versions: c-14.2 +language_pack: c-14.2 diff --git a/compiled_starters/c/your_program.sh b/compiled_starters/c/your_program.sh new file mode 100755 index 0000000..6101e9a --- /dev/null +++ b/compiled_starters/c/your_program.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Use this script to run your program LOCALLY. +# +# Note: Changing this script WILL NOT affect how CodeCrafters runs your program. +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit early if any commands fail + +# Copied from .codecrafters/compile.sh +# +# - Edit this to change how your program compiles locally +# - Edit .codecrafters/compile.sh to change how your program compiles remotely +( + cd "$(dirname "$0")" # Ensure compile steps are run within the repository directory + gcc -o /tmp/codecrafters-build-git-c app/*.c +) + +# Copied from .codecrafters/run.sh +# +# - Edit this to change how your program runs locally +# - Edit .codecrafters/run.sh to change how your program runs remotely +exec /tmp/codecrafters-build-git-c "$@" diff --git a/dockerfiles/c-14.2.Dockerfile b/dockerfiles/c-14.2.Dockerfile new file mode 100644 index 0000000..aafcddd --- /dev/null +++ b/dockerfiles/c-14.2.Dockerfile @@ -0,0 +1,13 @@ +# syntax=docker/dockerfile:1.7-labs +FROM gcc:14.2.0-bookworm + +# Ensures the container is re-built if dependency files change +# ENV CODECRAFTERS_DEPENDENCY_FILE_PATHS="" + +WORKDIR /app + +# .git & README.md are unique per-repository. We ignore them on first copy to prevent cache misses +COPY --exclude=.git --exclude=README.md . /app + +# Install language-specific dependencies +RUN .codecrafters/compile.sh diff --git a/solutions/c/01-gg4/code/.codecrafters/compile.sh b/solutions/c/01-gg4/code/.codecrafters/compile.sh new file mode 100755 index 0000000..4ef5842 --- /dev/null +++ b/solutions/c/01-gg4/code/.codecrafters/compile.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +gcc -o /tmp/codecrafters-build-git-c app/*.c diff --git a/solutions/c/01-gg4/code/.codecrafters/run.sh b/solutions/c/01-gg4/code/.codecrafters/run.sh new file mode 100755 index 0000000..1c93056 --- /dev/null +++ b/solutions/c/01-gg4/code/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec /tmp/codecrafters-build-git-c "$@" diff --git a/solutions/c/01-gg4/code/.gitattributes b/solutions/c/01-gg4/code/.gitattributes new file mode 100644 index 0000000..176a458 --- /dev/null +++ b/solutions/c/01-gg4/code/.gitattributes @@ -0,0 +1 @@ +* text=auto diff --git a/solutions/c/01-gg4/code/.gitignore b/solutions/c/01-gg4/code/.gitignore new file mode 100644 index 0000000..c6127b3 --- /dev/null +++ b/solutions/c/01-gg4/code/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/solutions/c/01-gg4/code/README.md b/solutions/c/01-gg4/code/README.md new file mode 100644 index 0000000..3ff2edc --- /dev/null +++ b/solutions/c/01-gg4/code/README.md @@ -0,0 +1,59 @@ +![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/git.png) + +This is a starting point for C solutions to the +["Build Your Own Git" Challenge](https://codecrafters.io/challenges/git). + +In this challenge, you'll build a small Git implementation that's capable of +initializing a repository, creating commits and cloning a public repository. +Along the way we'll learn about the `.git` directory, Git objects (blobs, +commits, trees etc.), Git's transfer protocols and more. + +**Note**: If you're viewing this repo on GitHub, head over to +[codecrafters.io](https://codecrafters.io) to try the challenge. + +# Passing the first stage + +The entry point for your Git implementation is in `app/main.c`. Study and +uncomment the relevant code, and push your changes to pass the first stage: + +```sh +git commit -am "pass 1st stage" # any msg +git push origin master +``` + +That's all! + +# Stage 2 & beyond + +Note: This section is for stages 2 and beyond. + +1. Ensure you have `gcc` installed locally +1. Run `./your_program.sh` to run your Git implementation, which is implemented + in `app/main.c`. +1. Commit your changes and run `git push origin master` to submit your solution + to CodeCrafters. Test output will be streamed to your terminal. + +# Testing locally + +The `your_program.sh` script is expected to operate on the `.git` folder inside +the current working directory. If you're running this inside the root of this +repository, you might end up accidentally damaging your repository's `.git` +folder. + +We suggest executing `your_program.sh` in a different folder when testing +locally. For example: + +```sh +mkdir -p /tmp/testing && cd /tmp/testing +/path/to/your/repo/your_program.sh init +``` + +To make this easier to type out, you could add a +[shell alias](https://shapeshed.com/unix-alias/): + +```sh +alias mygit=/path/to/your/repo/your_program.sh + +mkdir -p /tmp/testing && cd /tmp/testing +mygit init +``` diff --git a/solutions/c/01-gg4/code/app/main.c b/solutions/c/01-gg4/code/app/main.c new file mode 100644 index 0000000..cd77006 --- /dev/null +++ b/solutions/c/01-gg4/code/app/main.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + // Disable output buffering + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + if (argc < 2) { + fprintf(stderr, "Usage: ./your_program.sh []\n"); + return 1; + } + + const char* command = argv[1]; + + if (strcmp(command, "init") == 0) { + if (mkdir(".git", 0755) == -1 || + mkdir(".git/objects", 0755) == -1 || + mkdir(".git/refs", 0755) == -1) { + fprintf(stderr, "Failed to create directories: %s\n", strerror(errno)); + return 1; + } + + FILE* headFile = fopen(".git/HEAD", "w"); + if (headFile == NULL) { + fprintf(stderr, "Failed to create .git/HEAD file: %s\n", strerror(errno)); + return 1; + } + fprintf(headFile, "ref: refs/heads/main\n"); + fclose(headFile); + + printf("Initialized git directory\n"); + } else { + fprintf(stderr, "Unknown command %s\n", command); + return 1; + } + + return 0; +} diff --git a/solutions/c/01-gg4/code/codecrafters.yml b/solutions/c/01-gg4/code/codecrafters.yml new file mode 100644 index 0000000..0a06ac0 --- /dev/null +++ b/solutions/c/01-gg4/code/codecrafters.yml @@ -0,0 +1,11 @@ +# Set this to true if you want debug logs. +# +# These can be VERY verbose, so we suggest turning them off +# unless you really need them. +debug: false + +# Use this to change the C version used to run your code +# on Codecrafters. +# +# Available versions: c-14.2 +language_pack: c-14.2 diff --git a/solutions/c/01-gg4/code/your_program.sh b/solutions/c/01-gg4/code/your_program.sh new file mode 100755 index 0000000..6101e9a --- /dev/null +++ b/solutions/c/01-gg4/code/your_program.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Use this script to run your program LOCALLY. +# +# Note: Changing this script WILL NOT affect how CodeCrafters runs your program. +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit early if any commands fail + +# Copied from .codecrafters/compile.sh +# +# - Edit this to change how your program compiles locally +# - Edit .codecrafters/compile.sh to change how your program compiles remotely +( + cd "$(dirname "$0")" # Ensure compile steps are run within the repository directory + gcc -o /tmp/codecrafters-build-git-c app/*.c +) + +# Copied from .codecrafters/run.sh +# +# - Edit this to change how your program runs locally +# - Edit .codecrafters/run.sh to change how your program runs remotely +exec /tmp/codecrafters-build-git-c "$@" diff --git a/solutions/c/01-gg4/diff/app/main.c.diff b/solutions/c/01-gg4/diff/app/main.c.diff new file mode 100644 index 0000000..1a955fa --- /dev/null +++ b/solutions/c/01-gg4/diff/app/main.c.diff @@ -0,0 +1,62 @@ +@@ -1,46 +1,42 @@ + #include + #include + #include + #include + #include + + int main(int argc, char *argv[]) { + // Disable output buffering + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + if (argc < 2) { + fprintf(stderr, "Usage: ./your_program.sh []\n"); + return 1; + } + + const char* command = argv[1]; + + if (strcmp(command, "init") == 0) { +- // You can use print statements as follows for debugging, they'll be visible when running tests. +- fprintf(stderr, "Logs from your program will appear here!\n"); ++ if (mkdir(".git", 0755) == -1 || ++ mkdir(".git/objects", 0755) == -1 || ++ mkdir(".git/refs", 0755) == -1) { ++ fprintf(stderr, "Failed to create directories: %s\n", strerror(errno)); ++ return 1; ++ } + +- // Uncomment this block to pass the first stage +- // if (mkdir(".git", 0755) == -1 || +- // mkdir(".git/objects", 0755) == -1 || +- // mkdir(".git/refs", 0755) == -1) { +- // fprintf(stderr, "Failed to create directories: %s\n", strerror(errno)); +- // return 1; +- // } +- // +- // FILE* headFile = fopen(".git/HEAD", "w"); +- // if (headFile == NULL) { +- // fprintf(stderr, "Failed to create .git/HEAD file: %s\n", strerror(errno)); +- // return 1; +- // } +- // fprintf(headFile, "ref: refs/heads/main\n"); +- // fclose(headFile); +- // +- // printf("Initialized git directory\n"); ++ FILE* headFile = fopen(".git/HEAD", "w"); ++ if (headFile == NULL) { ++ fprintf(stderr, "Failed to create .git/HEAD file: %s\n", strerror(errno)); ++ return 1; ++ } ++ fprintf(headFile, "ref: refs/heads/main\n"); ++ fclose(headFile); ++ ++ printf("Initialized git directory\n"); + } else { + fprintf(stderr, "Unknown command %s\n", command); + return 1; + } + + return 0; + } diff --git a/solutions/c/01-gg4/explanation.md b/solutions/c/01-gg4/explanation.md new file mode 100644 index 0000000..a617944 --- /dev/null +++ b/solutions/c/01-gg4/explanation.md @@ -0,0 +1,31 @@ +The entry point for your Git implementation is in `app/main.c`. + +Study and uncomment the relevant code: + +```c +// Uncomment this block to pass the first stage +if (mkdir(".git", 0755) == -1 || + mkdir(".git/objects", 0755) == -1 || + mkdir(".git/refs", 0755) == -1) { + fprintf(stderr, "Failed to create directories: %s\n", strerror(errno)); + return 1; +} + +FILE* headFile = fopen(".git/HEAD", "w"); +if (headFile == NULL) { + fprintf(stderr, "Failed to create .git/HEAD file: %s\n", strerror(errno)); + return 1; +} +fprintf(headFile, "ref: refs/heads/main\n"); +fclose(headFile); + +printf("Initialized git directory\n"); +``` + +Push your changes to pass the first stage: + +``` +git add . +git commit -m "pass 1st stage" # any msg +git push origin master +``` diff --git a/starter_templates/c/code/.codecrafters/compile.sh b/starter_templates/c/code/.codecrafters/compile.sh new file mode 100755 index 0000000..4ef5842 --- /dev/null +++ b/starter_templates/c/code/.codecrafters/compile.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to compile your program on CodeCrafters +# +# This runs before .codecrafters/run.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +gcc -o /tmp/codecrafters-build-git-c app/*.c diff --git a/starter_templates/c/code/.codecrafters/run.sh b/starter_templates/c/code/.codecrafters/run.sh new file mode 100755 index 0000000..1c93056 --- /dev/null +++ b/starter_templates/c/code/.codecrafters/run.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# +# This script is used to run your program on CodeCrafters +# +# This runs after .codecrafters/compile.sh +# +# Learn more: https://codecrafters.io/program-interface + +set -e # Exit on failure + +exec /tmp/codecrafters-build-git-c "$@" diff --git a/starter_templates/c/code/.gitignore b/starter_templates/c/code/.gitignore new file mode 100644 index 0000000..c6127b3 --- /dev/null +++ b/starter_templates/c/code/.gitignore @@ -0,0 +1,52 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf diff --git a/starter_templates/c/code/app/main.c b/starter_templates/c/code/app/main.c new file mode 100644 index 0000000..8313113 --- /dev/null +++ b/starter_templates/c/code/app/main.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + // Disable output buffering + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + if (argc < 2) { + fprintf(stderr, "Usage: ./your_program.sh []\n"); + return 1; + } + + const char* command = argv[1]; + + if (strcmp(command, "init") == 0) { + // You can use print statements as follows for debugging, they'll be visible when running tests. + fprintf(stderr, "Logs from your program will appear here!\n"); + + // Uncomment this block to pass the first stage + // if (mkdir(".git", 0755) == -1 || + // mkdir(".git/objects", 0755) == -1 || + // mkdir(".git/refs", 0755) == -1) { + // fprintf(stderr, "Failed to create directories: %s\n", strerror(errno)); + // return 1; + // } + // + // FILE* headFile = fopen(".git/HEAD", "w"); + // if (headFile == NULL) { + // fprintf(stderr, "Failed to create .git/HEAD file: %s\n", strerror(errno)); + // return 1; + // } + // fprintf(headFile, "ref: refs/heads/main\n"); + // fclose(headFile); + // + // printf("Initialized git directory\n"); + } else { + fprintf(stderr, "Unknown command %s\n", command); + return 1; + } + + return 0; +} diff --git a/starter_templates/c/config.yml b/starter_templates/c/config.yml new file mode 100644 index 0000000..dc25942 --- /dev/null +++ b/starter_templates/c/config.yml @@ -0,0 +1,3 @@ +attributes: + required_executable: 'gcc' + user_editable_file: 'app/main.c'