This article doesn't exist
} 25 |
2 |
3 |
8 | Features • 9 | Upcoming Features • 10 | Supported Commands • 11 | Contribute 12 |
13 | 14 | ## Introduction 15 | 16 | This project is written with Typescript using React. It works only with a front-end, using parsing of command-line arguments and a simple .json file containing all the descriptions of the commands and their flags. It is also easy to self-host since it doesn't contain a server. 17 | 18 | ## Features 19 | 20 | What The Git only contains really basic git commands and flags so far, but the list will grow with time. I expect to support at least git add, git commit and git push. Feel free to contribute to fix issues that you found in the app or to add more git commands to it ! As this is a personal project, I would really appreciate it. 21 | 22 | It also features a system that embeds descriptions of git jargon such as staging area, commit etc. as hyperlinks in the command description. You can either hover them to see a short description, or click the "read article" button to be redirected on the full article. 23 | 24 | ## Upcoming features 25 | 26 | - More verbose errors (telling you where the command went wrong and why instead of just showing a generic error message) 27 | 28 | Feel free to submit an issue if you have feature requests, I'll gladly take them. 29 | 30 | ## Supported commands 31 | 32 | So far, only a few commands are supported, with a few flags: 33 | 34 | - git 35 | - add 36 | - commit 37 | - push 38 | - rebase 39 | - diff 40 | - log 41 | - pull 42 | - status 43 | 44 | ## Contribute 45 | 46 | As I stated above, pull requests, bug reports and feature requests are very much appreciated. This is a big project for me, and any help would be truly appreciated! I setup a couple of templates in the issues section if you want to contribute. I don't feel like adding a code of conduct, I only expect contributors to be respectful to each other. 47 | 48 | It is advised to read the [developer manual](DEVELOPMENT.md) before intending to contribute on the code. It's here to help you understand the structure of the project! 49 | 50 | ## Development 51 | 52 | ### Disclaimer 53 | 54 | This project now uses yarn, which is an alternative package manager for NodeJS. You can find it at https://yarnpkg.com/ if you don't already have it installed on your system. 55 | 56 | ### Run the app on a local machine 57 | 58 | In the project directory, you can run: 59 | 60 | ### `yarn` 61 | 62 | Runs yarn and downloads the related packages, and it's dependencies for this project 63 | 64 | ### `yarn run start` 65 | 66 | Runs the app in the development mode.\ 67 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 68 | 69 | The page will reload if you make edits.\ 70 | You will also see any lint errors in the console. 71 | 72 | ### `yarn run build` 73 | 74 | Builds the app for production to the `build` folder.\ 75 | It correctly bundles React in production mode and optimizes the build for the best performance. 76 | 77 | The build is minified, and the filenames include the hashes.\ 78 | Your app is ready to be deployed! 79 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import parser from 'yargs-parser' 2 | import { useState } from 'react' 3 | import './App.css' 4 | import { gitCommands, specialTokens } from './git-commands' 5 | import { 6 | getAvailableFlagsAsArray, 7 | getMatchingFlags, 8 | getParsedFlagsDescriptions, 9 | getAliasesAsObject, 10 | replaceSpecialTokens, 11 | parseDescription, 12 | } from './git-command-parsing' 13 | import { GitCommand, InputFlag } from './types' 14 | import { definitions } from './git-definitions' 15 | 16 | // Gets the matching git command from the git-commands.js file, and formats the description using the arguments if needed. 17 | function getGitCommand(inputCommand: string): GitCommand | null { 18 | // Get the command name and check if it exists 19 | const inputCommandName = inputCommand.split(' ')[1] 20 | const matchingCommand = gitCommands.commands.find((command) => command.name === inputCommandName) 21 | if (!(inputCommand.split(' ')[0] === 'git') || !matchingCommand) { 22 | return null 23 | } 24 | 25 | // Get all the available flags 26 | const availableFlags = gitCommands.commands.find((command) => command.name === inputCommandName) 27 | ?.flags 28 | 29 | // These arrays exist so they can be used with yargs-parser 30 | let availableFlagsAsArrays 31 | let aliasesObject 32 | 33 | if (availableFlags) { 34 | availableFlagsAsArrays = getAvailableFlagsAsArray(availableFlags) 35 | aliasesObject = getAliasesAsObject(availableFlags) 36 | } 37 | 38 | // Parse the arguments 39 | const parsedArgs = parser(inputCommand, { 40 | boolean: availableFlagsAsArrays?.booleanFlagsArray, 41 | string: availableFlagsAsArrays?.stringFlagsArray, 42 | alias: aliasesObject, 43 | }) 44 | 45 | // Restructure the arguments to be easier to work with 46 | // Instead of the flags being as keys value pairs in the object, put them in their own property called flags with a name and a value 47 | const parsedArguments = Object.entries(parsedArgs).reduce( 48 | (acc, [argumentKey, argumentValue]) => { 49 | if (argumentKey === '_') { 50 | return { ...acc, _: argumentValue } 51 | } 52 | if (argumentValue) { 53 | acc.flags.push({ name: argumentKey, value: argumentValue }) 54 | } 55 | return acc 56 | }, 57 | { _: [] as string[], flags: [] as InputFlag[] } 58 | ) 59 | 60 | let matchingFlags 61 | if (availableFlags) { 62 | matchingFlags = getMatchingFlags(availableFlags, parsedArguments) 63 | } 64 | 65 | // Check if the arguments contain special tokens and replace them by the description to be displayed in the description 66 | const updatedParsedArguments = replaceSpecialTokens(parsedArguments, specialTokens) 67 | 68 | // Replace string tokens with arguments and add a list of flags descriptions if needed 69 | const updatedMatchingCommand = { 70 | ...matchingCommand, 71 | description: parseDescription( 72 | matchingCommand as GitCommand, 73 | definitions, 74 | updatedParsedArguments 75 | ), 76 | flagsDescriptions: getParsedFlagsDescriptions(matchingFlags || [], updatedParsedArguments), 77 | } 78 | 79 | return updatedMatchingCommand 80 | } 81 | 82 | function renderCommandDescription(command: GitCommand) { 83 | let flagsDescriptions 84 | if (command.flagsDescriptions.length > 0) { 85 | flagsDescriptions = command.flagsDescriptions.map((flag) => { 86 | return ( 87 |{flag.description}
93 |{command.description}
102 | {flagsDescriptions &&