├── logo-1024.png ├── .0pdd.yml ├── .gitignore ├── cucumber.yml ├── .pdd ├── docker ├── README.md └── Dockerfile ├── .gitattributes ├── features ├── cli.feature ├── gem_package.feature ├── support │ └── env.rb └── step_definitions │ └── steps.rb ├── .rultor.yml ├── .rubocop.yml ├── LICENSE.txt ├── Gemfile ├── lib ├── degit.rb └── degit │ ├── version.rb │ ├── deploy.rb │ └── dashboard.rb ├── test ├── test__helper.rb └── test_degit.rb ├── .simplecov ├── logo.svg ├── bin └── degit ├── Rakefile ├── degit.gemspec └── README.md /logo-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cqfn/degit/HEAD/logo-1024.png -------------------------------------------------------------------------------- /.0pdd.yml: -------------------------------------------------------------------------------- 1 | errors: 2 | - yegor256@gmail.com 3 | tags: 4 | - pdd 5 | - bug 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage/ 2 | Gemfile.lock 3 | .idea/ 4 | *.gem 5 | .bundle/ 6 | .DS_Store 7 | rdoc/ 8 | tmp/ 9 | -------------------------------------------------------------------------------- /cucumber.yml: -------------------------------------------------------------------------------- 1 | default: --format pretty 2 | travis: --format progress 3 | html_report: --format progress --format html --out=features_report.html 4 | -------------------------------------------------------------------------------- /.pdd: -------------------------------------------------------------------------------- 1 | --source=. 2 | --verbose 3 | --exclude target/**/* 4 | --exclude coverage/**/* 5 | --rule min-words:20 6 | --rule min-estimate:15 7 | --rule max-estimate:90 8 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | [![Docker Cloud Automated build](https://img.shields.io/docker/cloud/automated/cqfn/degit)](https://hub.docker.com/r/cqfn/degit) 2 | 3 | Run it like this: 4 | 5 | ```bash 6 | $ docker --rm -p 22:22 -v /var/degit:/home/git cqfn/degit 7 | ``` 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Check out all text files in UNIX format, with LF as end of line 2 | # Don't change this file. If you have any ideas about it, please 3 | # submit a separate issue about it and we'll discuss. 4 | 5 | * text=auto eol=lf 6 | *.rb ident 7 | *.xml ident 8 | -------------------------------------------------------------------------------- /features/cli.feature: -------------------------------------------------------------------------------- 1 | Feature: Command Line Processing 2 | As a newsletter author I want to be able to send a newsletter 3 | 4 | Scenario: Help can be printed 5 | When I run bin/degit with "--help" 6 | Then Exit code is zero 7 | And Stdout contains "--help" 8 | -------------------------------------------------------------------------------- /.rultor.yml: -------------------------------------------------------------------------------- 1 | assets: 2 | rubygems.yml: yegor256/home#assets/rubygems.yml 3 | install: | 4 | pdd -f /dev/null 5 | sudo bundle install --no-color "--gemfile=$(pwd)/Gemfile" 6 | release: 7 | script: |- 8 | bundle exec rake clean test rubocop copyright 9 | sed -i "s/1\.0\.snapshot/${tag}/g" lib/degit/version.rb 10 | git add lib/degit/version.rb 11 | git commit -m "version set to ${tag}" 12 | gem build degit.gemspec 13 | chmod 0600 ../rubygems.yml 14 | gem push *.gem --config-file ../rubygems.yml 15 | merge: 16 | script: |- 17 | bundle exec rake clean test rubocop copyright 18 | deploy: 19 | script: |- 20 | echo "There is nothing to deploy" 21 | exit -1 22 | -------------------------------------------------------------------------------- /features/gem_package.feature: -------------------------------------------------------------------------------- 1 | Feature: Gem Package 2 | As a source code writer I want to be able to 3 | package the Gem into .gem file 4 | 5 | Scenario: Gem can be packaged 6 | Given It is Unix 7 | Given I have a "execs.rb" file with content: 8 | """ 9 | #!/usr/bin/env ruby 10 | require 'rubygems' 11 | spec = Gem::Specification::load('./spec.rb') 12 | if spec.executables.empty? 13 | fail 'no executables: ' + File.read('./spec.rb') 14 | end 15 | """ 16 | When I run bash with: 17 | """ 18 | cd degit 19 | gem build degit.gemspec 20 | gem specification --ruby degit-*.gem > ../spec.rb 21 | cd .. 22 | ruby execs.rb 23 | """ 24 | Then Exit code is zero 25 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | Exclude: 3 | - 'assets/**/*' 4 | DisplayCopNames: true 5 | TargetRubyVersion: 2.3 6 | 7 | Style/ClassAndModuleChildren: 8 | Enabled: false 9 | Metrics/LineLength: 10 | Max: 100 11 | Layout/EndOfLine: 12 | EnforcedStyle: lf 13 | Metrics/CyclomaticComplexity: 14 | Max: 20 15 | Metrics/MethodLength: 16 | Enabled: false 17 | Layout/MultilineMethodCallIndentation: 18 | Enabled: false 19 | Metrics/ParameterLists: 20 | Max: 6 21 | Metrics/ClassLength: 22 | Max: 250 23 | Metrics/AbcSize: 24 | Enabled: false 25 | Metrics/BlockLength: 26 | Max: 100 27 | Metrics/PerceivedComplexity: 28 | Max: 20 29 | Style/MultilineTernaryOperator: 30 | Enabled: false 31 | Layout/EmptyLineAfterGuardClause: 32 | Enabled: false 33 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2020 Yegor Bugayenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the 'Software'), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | source 'https://rubygems.org' 24 | ruby '~>2.3' 25 | gemspec 26 | -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | require 'simplecov' 24 | require_relative '../../lib/degit' 25 | -------------------------------------------------------------------------------- /lib/degit.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | require_relative 'degit/version' 24 | 25 | # Degit main class. 26 | # 27 | # Author:: Yegor Bugayenko (yegor256@gmail.com) 28 | # Copyright:: Copyright (c) 2020 Yegor Bugayenko 29 | # License:: MIT 30 | module Degit 31 | end 32 | -------------------------------------------------------------------------------- /lib/degit/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | # Degit main class. 24 | # Author:: Yegor Bugayenko (yegor256@gmail.com) 25 | # Copyright:: Copyright (c) 2020 Yegor Bugayenko 26 | # License:: MIT 27 | module Degit 28 | # Current version of the library. 29 | VERSION = '0.0.0' 30 | end 31 | -------------------------------------------------------------------------------- /test/test__helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | STDOUT.sync = true 24 | 25 | require 'simplecov' 26 | SimpleCov.start 27 | if ENV['CI'] == 'true' 28 | require 'codecov' 29 | SimpleCov.formatter = SimpleCov::Formatter::Codecov 30 | end 31 | 32 | require 'minitest/autorun' 33 | require_relative '../lib/degit' 34 | -------------------------------------------------------------------------------- /test/test_degit.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | require 'minitest/autorun' 24 | require_relative '../lib/degit' 25 | 26 | # Degit. 27 | # Author:: Yegor Bugayenko (yegor256@gmail.com) 28 | # Copyright:: Copyright (c) 2020 Yegor Bugayenko 29 | # License:: MIT 30 | class TestDegit < Minitest::Test 31 | def test_works 32 | assert_equal(1, 1) 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /lib/degit/deploy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | require 'loog' 24 | 25 | # Deploy. 26 | # Author:: Yegor Bugayenko (yegor256@gmail.com) 27 | # Copyright:: Copyright (c) 2020 Yegor Bugayenko 28 | # License:: MIT 29 | class Degit::Deploy 30 | # Current version of the library. 31 | def initialize(log: Loog::NULL) 32 | @log = log 33 | end 34 | 35 | def go 36 | @log.info('To be continued...') 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/degit/dashboard.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | require 'loog' 24 | 25 | # Dashboard. 26 | # Author:: Yegor Bugayenko (yegor256@gmail.com) 27 | # Copyright:: Copyright (c) 2020 Yegor Bugayenko 28 | # License:: MIT 29 | class Degit::Dashboard 30 | # Current version of the library. 31 | def initialize(log: Loog::NULL) 32 | @log = log 33 | end 34 | 35 | def go 36 | @log.info('To be continued...') 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /.simplecov: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Yegor Bugayenko 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the 'Software'), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | if Gem.win_platform? then 22 | SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ 23 | SimpleCov::Formatter::HTMLFormatter 24 | ] 25 | SimpleCov.start do 26 | add_filter "/test/" 27 | add_filter "/features/" 28 | end 29 | else 30 | SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new( 31 | [SimpleCov::Formatter::HTMLFormatter] 32 | ) 33 | SimpleCov.start do 34 | add_filter "/test/" 35 | add_filter "/features/" 36 | minimum_coverage 60 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Yegor Bugayenko 2 | # 3 | # Permission is hereby granted, free of charge, to any person obtaining a copy 4 | # of this software and associated documentation files (the 'Software'), to deal 5 | # in the Software without restriction, including without limitation the rights 6 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | # copies of the Software, and to permit persons to whom the Software is 8 | # furnished to do so, subject to the following conditions: 9 | # 10 | # The above copyright notice and this permission notice shall be included in all 11 | # copies or substantial portions of the Software. 12 | # 13 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 16 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | # SOFTWARE. 20 | 21 | # This image is making the server fully ready to work as a node in 22 | # DeGit network. 23 | 24 | FROM ubuntu:18.04 25 | MAINTAINER Yegor Bugayenko 26 | LABEL Description="This is the default image for DeGit" Vendor="DeGit" Version="1.0" 27 | WORKDIR /tmp 28 | 29 | ENV DEBIAN_FRONTEND=noninteractive 30 | 31 | RUN apt-get update -y 32 | RUN apt-get install -y openssh-server git 33 | RUN mkdir -p /var/run/sshd 34 | 35 | RUN mkdir -p /usr/local/bin/degit 36 | RUN mv /usr/bin/git /usr/local/bin/degit/git 37 | RUN for i in git-receive-pack git-upload-archive git-upload-pack; do ln -s /usr/local/bin/degit/git "/usr/local/bin/degit/${i}"; done 38 | 39 | ENTRYPOINT ["/usr/sbin/sshd", "-D", "-o", "ListenAddress=0.0.0.0"] 40 | -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 2 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /bin/degit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # Copyright (c) 2020 Yegor Bugayenko 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the 'Software'), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | 24 | STDOUT.sync = true 25 | 26 | require 'slop' 27 | require 'backtrace' 28 | require_relative '../lib/degit/version' 29 | require_relative '../lib/degit/deploy' 30 | 31 | begin 32 | begin 33 | opts = Slop.parse(ARGV, strict: true, help: true) do |o| 34 | o.banner = "Usage (#{Degit::VERSION}): degit [options] command [args] 35 | Commands are: 36 | run: Run the dashboard 37 | deploy: Make sure the server is ready to be part of DeGit network 38 | Options are:" 39 | o.bool '--help', 'Read this: https://github.com/yegor256/degit' do 40 | puts o 41 | exit 42 | end 43 | o.bool '--verbose', 'Print all possible debug messages' 44 | end 45 | rescue Slop::Error => ex 46 | raise ex.message 47 | end 48 | raise 'Try --help' if opts.arguments.empty? 49 | log = opts[:verbose] ? Loog::VERBOSE : Loog::REGULAR 50 | case opts.arguments[0] 51 | when 'run' 52 | Degit::Dashboard.new(log: log).go 53 | when 'deploy' 54 | Degit::Deploy.new(log: log).go 55 | else 56 | raise "Command #{opts.arguments[0]} is not supported" 57 | end 58 | rescue StandardError => ex 59 | if opts[:verbose] 60 | puts Backtrace.new(ex).to_s 61 | else 62 | puts "ERROR: #{ex.message}" 63 | end 64 | exit(255) 65 | end 66 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | require 'rubygems' 24 | require 'rake' 25 | require 'rdoc' 26 | require 'rake/clean' 27 | 28 | def name 29 | @name ||= File.basename(Dir['*.gemspec'].first, '.*') 30 | end 31 | 32 | def version 33 | Gem::Specification.load(Dir['*.gemspec'].first).version 34 | end 35 | 36 | task default: %i[clean test features rubocop copyright] 37 | 38 | require 'rake/testtask' 39 | Rake::TestTask.new(:test) do |test| 40 | ENV['skip_live'] = 'yes' 41 | Rake::Cleaner.cleanup_files(['coverage']) 42 | test.libs << 'lib' << 'test' 43 | test.pattern = 'test/**/test_*.rb' 44 | test.verbose = false 45 | end 46 | 47 | require 'rdoc/task' 48 | Rake::RDocTask.new do |rdoc| 49 | rdoc.rdoc_dir = 'rdoc' 50 | rdoc.title = "#{name} #{version}" 51 | rdoc.rdoc_files.include('README*') 52 | rdoc.rdoc_files.include('lib/**/*.rb') 53 | end 54 | 55 | require 'rubocop/rake_task' 56 | RuboCop::RakeTask.new(:rubocop) do |task| 57 | task.fail_on_error = true 58 | task.requires << 'rubocop-rspec' 59 | end 60 | 61 | require 'cucumber/rake/task' 62 | Cucumber::Rake::Task.new(:features) do 63 | Rake::Cleaner.cleanup_files(['coverage']) 64 | end 65 | Cucumber::Rake::Task.new(:'features:html') do |t| 66 | t.profile = 'html_report' 67 | end 68 | 69 | task :copyright do 70 | sh "grep -q -r '#{Date.today.strftime('%Y')}' \ 71 | --include '*.rb' \ 72 | --include '*.txt' \ 73 | --include 'Rakefile' \ 74 | ." 75 | end 76 | -------------------------------------------------------------------------------- /degit.gemspec: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | require 'English' 24 | 25 | lib = File.expand_path('lib', __dir__) 26 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 27 | require_relative 'lib/degit/version' 28 | Gem::Specification.new do |s| 29 | s.specification_version = 2 if s.respond_to? :specification_version= 30 | if s.respond_to? :required_rubygems_version= 31 | s.required_rubygems_version = Gem::Requirement.new('>= 0') 32 | end 33 | s.rubygems_version = '2.2' 34 | s.required_ruby_version = '>= 2.3' 35 | s.name = 'degit' 36 | s.version = Degit::VERSION 37 | s.license = 'MIT' 38 | s.summary = 'Decentralized GitHub' 39 | s.description = 'This is a simple prototype of a decentralized GitHub' 40 | s.authors = ['Yegor Bugayenko'] 41 | s.email = 'yegor256@gmail.com' 42 | s.homepage = 'http://github.com/yegor256/degit' 43 | s.files = `git ls-files`.split($RS) 44 | s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) } 45 | s.test_files = s.files.grep(%r{^(test|spec|features)/}) 46 | s.rdoc_options = ['--charset=UTF-8'] 47 | s.extra_rdoc_files = ['README.md', 'LICENSE.txt'] 48 | s.add_runtime_dependency 'backtrace', '~> 0.3' 49 | s.add_runtime_dependency 'loog', '0.2.1' 50 | s.add_runtime_dependency 'slop', '~> 4.6' 51 | s.add_development_dependency 'codecov', '0.1.10' 52 | s.add_development_dependency 'cucumber', '~> 1.3.17' 53 | s.add_development_dependency 'minitest', '5.5.0' 54 | s.add_development_dependency 'rake', '12.0.0' 55 | s.add_development_dependency 'rubocop', '0.61.0' 56 | s.add_development_dependency 'rubocop-rspec', '1.31.0' 57 | end 58 | -------------------------------------------------------------------------------- /features/step_definitions/steps.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright (c) 2020 Yegor Bugayenko 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the 'Software'), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | require 'tmpdir' 24 | require 'slop' 25 | require 'English' 26 | require_relative '../../lib/degit' 27 | 28 | Before do 29 | @cwd = Dir.pwd 30 | @dir = Dir.mktmpdir('test') 31 | FileUtils.mkdir_p(@dir) unless File.exist?(@dir) 32 | Dir.chdir(@dir) 33 | @opts = Slop.parse ['-v', '-s', @dir] do |o| 34 | o.bool '-v', '--verbose' 35 | o.string '-s', '--source' 36 | end 37 | end 38 | 39 | After do 40 | Dir.chdir(@cwd) 41 | FileUtils.rm_rf(@dir) if File.exist?(@dir) 42 | end 43 | 44 | Given(/^I have a "([^"]*)" file with content:$/) do |file, text| 45 | FileUtils.mkdir_p(File.dirname(file)) unless File.exist?(file) 46 | File.open(file, 'w') do |f| 47 | f.write(text.gsub(/\\xFF/, 0xFF.chr)) 48 | end 49 | end 50 | 51 | When(%r{^I run bin/degit with "([^"]*)"$}) do |arg| 52 | home = File.join(File.dirname(__FILE__), '../..') 53 | @stdout = `ruby -I#{home}/lib #{home}/bin/degit #{arg}` 54 | @exitstatus = $CHILD_STATUS.exitstatus 55 | end 56 | 57 | Then(/^Stdout contains "([^"]*)"$/) do |txt| 58 | raise "STDOUT doesn't contain '#{txt}':\n#{@stdout}" unless @stdout.include?(txt) 59 | end 60 | 61 | Then(/^Stdout is empty$/) do 62 | raise "STDOUT is not empty:\n#{@stdout}" unless @stdout == '' 63 | end 64 | 65 | Then(/^Exit code is zero$/) do 66 | raise "Non-zero exit #{@exitstatus}:\n#{@stdout}" unless @exitstatus.zero? 67 | end 68 | 69 | Then(/^Exit code is not zero$/) do 70 | raise 'Zero exit code' if @exitstatus.zero? 71 | end 72 | 73 | When(/^I run bash with "([^"]*)"$/) do |text| 74 | FileUtils.copy_entry(@cwd, File.join(@dir, 'degit')) 75 | @stdout = `#{text}` 76 | @exitstatus = $CHILD_STATUS.exitstatus 77 | end 78 | 79 | When(/^I run bash with:$/) do |text| 80 | FileUtils.copy_entry(@cwd, File.join(@dir, 'degit')) 81 | @stdout = `#{text}` 82 | @exitstatus = $CHILD_STATUS.exitstatus 83 | end 84 | 85 | Given(/^It is Unix$/) do 86 | pending if Gem.win_platform? 87 | end 88 | 89 | Given(/^It is Windows$/) do 90 | pending unless Gem.win_platform? 91 | end 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [![EO principles respected here](https://www.elegantobjects.org/badge.svg)](https://www.elegantobjects.org) 4 | [![DevOps By Rultor.com](http://www.rultor.com/b/cqfn/degit)](http://www.rultor.com/p/cqfn/degit) 5 | [![We recommend RubyMine](https://www.elegantobjects.org/rubymine.svg)](https://www.jetbrains.com/ruby/) 6 | 7 | [![PDD status](http://www.0pdd.com/svg?name=cqfn/degit)](http://www.0pdd.com/p?name=cqfn/degit) 8 | [![Gem Version](https://badge.fury.io/rb/degit.svg)](http://badge.fury.io/rb/degit) 9 | [![Maintainability](https://api.codeclimate.com/v1/badges/74c909f06d4afa0d8001/maintainability)](https://codeclimate.com/github/cqfn/degit/maintainability) 10 | 11 | [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/yegor256/takes/degit/master/LICENSE.txt) 12 | [![Test Coverage](https://img.shields.io/codecov/c/github/cqfn/degit.svg)](https://codecov.io/github/cqfn/degit?branch=master) 13 | [![Hits-of-Code](https://hitsofcode.com/github/cqfn/degit)](https://hitsofcode.com/view/github/cqfn/degit) 14 | 15 | DeGit is a decentralized [Git](https://git-scm.com/) projects hosting platform. 16 | You can join by starting a node and pointing your browser 17 | at `127.0.0.1`. Then, just work with it as if it was GitHub. 18 | There is no central point of failure, 19 | since the network of DeGit nodes is run by anonymous volunteers. 20 | 21 | To start, simply do (it uses your `.ssh/id_rsa` for authentication): 22 | 23 | ```bash 24 | $ gem install degit 25 | $ degit run 26 | ``` 27 | 28 | In a few seconds you can open `https://localhost:8080` and enjoy 29 | the system, which is very similar to GitHub. You can, of course, use 30 | local Git repo, which is on-fly synchronized with other DeGit nodes. 31 | 32 | ## Motivation and Related Works 33 | 34 | We are not the first who are thinking about a decentralized solution 35 | for hosting and managing of Git repositories. There were a few similar products 36 | created before (if you know anything else, please submit a pull request): 37 | 38 | * [GitChain](http://gitchain.org/) (abandoned in 2014) 39 | * [GitTorrent](https://github.com/cjb/GitTorrent) (abandoned in 2015) 40 | * [Drepo](https://www.drepo.io/) (abandoned in 2018) 41 | * [Radicle](https://github.com/radicle-dev) (read [this](https://outlierventures.io/wp-content/uploads/2019/11/Radicle-Diffusion-2019-1.pdf)) 42 | * [git-issue](https://github.com/dspinellis/git-issue) 43 | * [git-ssb](https://scuttlebot.io/apis/community/git-ssb.html) 44 | * [git-dit](https://github.com/neithernut/git-dit) 45 | * [pando](https://github.com/pandonetwork/pando) 46 | * [mango](https://github.com/axic/mango) (abandoned in 2016, watch [this](https://www.youtube.com/watch?v=tU7_Yf45okc)) 47 | * [ZeroNet](https://zeronet.io/) (not exactly Git, but relevant) 48 | 49 | Even though [GitHub](https://github.com), 50 | [GitLab](https://gitlab.com), 51 | [BitBucket](https://bitbucket.com), 52 | [Phabricator](https://phacility.com/phabricator/), 53 | [SourceForge](https://sourceforge.net/), 54 | [CodeCommit](https://console.aws.amazon.com/codecommit/home), 55 | and 56 | [Gitee](https://gitee.com) are great platforms, 57 | they have three critical drawbacks: 58 | 59 | * They are [not](https://news.ycombinator.com/item?id=20499070) 100% reliable, 60 | * They [ban](https://medium.com/@catamphetamine/how-github-blocked-me-and-all-my-libraries-c32c61f061d3) 61 | users for 62 | [almost](https://medium.com/@hamed/github-blocked-my-account-and-they-think-im-developing-nuclear-weapons-e7e1fe62cb74) 63 | [no reason](https://en.wikipedia.org/wiki/Censorship_of_GitHub), and 64 | * They are under the [influence](https://techcrunch.com/2019/07/29/github-ban-sanctioned-countries/) of their local governments. 65 | 66 | It seems that the need for a decentralized solution is obvious. 67 | We believe that the community would enjoy having a platform 68 | with the following features: 69 | 70 | * [Pull requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests); 71 | * Issues and milestones; 72 | * Stars and followers; 73 | * GitHub-like web user interface; 74 | * Entirely free for everybody; 75 | * Not owned by anyone; 76 | * Moderated by the board of deputies. 77 | 78 | DeGit doesn't support private repositories, only public ones. 79 | 80 | ## How to Start? 81 | 82 | If you want to use DeGit in order to host your repositories, 83 | just like you use GitHub, read the instructions above: they 84 | are very simple. 85 | If you want to run a node and contribute to DeGit network with your 86 | storage and computational resources, here is how: 87 | 88 | First, you install 89 | [Ruby 2.6+](https://www.ruby-lang.org/en/) and 90 | [Docker](https://docs.docker.com/get-docker/) 91 | (we recommend you to use [Ubuntu 18.04](https://releases.ubuntu.com/18.04/)). 92 | 93 | Then, you make a directory, where Git repositories will be maintained. By default, 94 | it's `/var/degit`. 95 | 96 | Next, you run this (make sure you don't have SSHD running on the server, or you will 97 | have a conflict on the port 22 already open): 98 | 99 | ```bash 100 | $ docker run --rm --port 22:22 --volume /var/degit:/home/git cqfn/degit 101 | ``` 102 | 103 | The container will start and you will have an ability to manage it via 104 | command line `degit` tool. For example, to limit the amount of repositories 105 | it hosts to 100, you just run: 106 | 107 | ```bash 108 | $ degit config max.repositories 100 109 | ``` 110 | 111 | The command line `degit` tool just makes changes to the files located in 112 | `/var/degit`, which are respected by the scripts inside the Docker container 113 | running. 114 | 115 | ## How It Works? 116 | 117 | The following principles are behind the architecture of DeGit: 118 | 119 | * `.degit` directory in `master` branch is used to keep meta information 120 | * Ownership of a repo is defined by public [RSA](https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29) keys in `.degit` 121 | * Issues, PRs, comments, stars, etc. are regular files in `.degit` 122 | * Issues, PRs, and comments have hash codes instead of sequential IDs 123 | * Each node decides for itself which repositories to host 124 | * Give-and-take principle is in place: "The more you host for me, the more I host for you" 125 | * Conflicts are resolved through proof-of-availability (PoA) consensus 126 | * Neighbours-discovery protocol is similar to the one used in [Zold](https://blog.zold.io/2018/12/28/nodes-discovery-protocol.html) 127 | 128 | ### Architecture 129 | 130 | There are a few components in the system: 131 | 132 | 133 | 134 | The **Dashboard** is a web server with a GitHub-like interface 135 | to let user manage issues, pull requests, milestones and so on. 136 | 137 | The **Locator** is the dispatcher of requests through the network 138 | of DeGit nodes. When the user is trying to access the server that 139 | doesn't have the repository the user is looking for, the Locator 140 | makes a tunnel to another server and redirects the request there. 141 | 142 | The **Authenticator** is responsible for permissions validating 143 | and may rely on some external services, like LDAP (in case of 144 | enterprise deployment). 145 | 146 | The **Propagator** makes sure that changes pushed to the server 147 | are being sent to other servers right after they are accepted. 148 | 149 | ### Data Flow Explained 150 | 151 | "Availability" is a non-negative integer assigned by a node to each of its neighbours. 152 | The number goes up on every successful interaction with the neighbour. The 153 | number goes double-down on each network failure or any other 154 | non-logical error. 155 | 156 | Here is how the data is propagated when you interact with Git on your laptop 157 | (the same happens automatically behind the scene if you use UI in the browser): 158 | 159 | * You `git commit` your changes to your branches 160 | * You do `git push` to your `localhost` 161 | * On success, a built-in post-commit [hook](https://git-scm.com/docs/githooks) proceeds: 162 | * It `git fetch` from the first neighbour with the highest availability 163 | * It `git merge` if possible and all commits are signed correctly 164 | * It `git push` back to the neighbour 165 | 166 | It is highly recommended to avoid pushing to the 167 | same branch from a few nodes, 168 | since it may lead to inability to merge and abandonded 169 | (or lost) branches. 170 | 171 | ### Authorization and Authentication 172 | 173 | A repository has a list of files in `.degit/permissions` directory. Each file 174 | starts with a public RSA key and lists user IDs, permissions, etc. 175 | 176 | On each `git push` event, post-commit hook goes through the list of added 177 | commits and verifies permissions of each user. If any rule from 178 | `.degit/permissions` is not respected, the entire `push` operation is rejected. 179 | 180 | It is recommended to have at least two users with write access to the `master` 181 | branch, in order to avoid losing access to the repo when 182 | private RSA key is lost. 183 | 184 | ### Incentives 185 | 186 | Unlike [Blockchain](https://en.wikipedia.org/wiki/Blockchain), 187 | a full duplication of all database in all nodes is not 188 | required for DeGit. Instead, if a few nodes have the data of a repository, 189 | this may be enough for the majority of cases. Thus, each node tries to 190 | host a limited number of repositories, according to the disc space available. 191 | 192 | Also, each node maintains a list of repositories seen along with the addresses of their 193 | hosting nodes. When a `git fetch` arrives for a repository that 194 | the node doesn't have, it returns an error and a suggested list of nodes 195 | to ask for this repo. 196 | 197 | Thus, no monetary incentives are provided to node owners, but they are not 198 | expected to contribute large computational or storage resources to the system 199 | (like it happens in [Bitcoin](https://en.wikipedia.org/wiki/Bitcoin), for example). 200 | 201 | ### Anti-Spam 202 | 203 | [Vandalism](https://en.wikipedia.org/wiki/Vandalism) 204 | is possible through new issues and comments: they may be 205 | submitted in large amounts. In order to fight against this, users may use 206 | scripts (a concept very close to [smart contracts](https://en.wikipedia.org/wiki/Smart_contract)) 207 | to be executed on each post-commit hook to check 208 | the validity of data submitted to `.degit`. 209 | 210 | ### Moderation 211 | 212 | To be continued... 213 | 214 | ### DeGit for Enterprise 215 | 216 | Out-of-the box version of DeGit doesn't support private repositories. Here 217 | is how it may be modified to be hosted inside a company, to support 218 | in-house user authentication and restrict access to certain repositories 219 | (this is just an example): 220 | 221 | 222 | 223 | Each Web Node is running a Dashboard, which is getting 224 | access information from [LDAP](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) 225 | through the **AM** (Authentication Module). The AM has all the information 226 | about all enterprise users and enables an additional layer of access 227 | granting on top of RSA keys. 228 | 229 | The **DB** (Database) contains the entire map of all servers running 230 | Git in the enterprise and makes it easier for each node to detect the 231 | right location of a repository and redirect requests. It also, being 232 | a place of centralization, enables synchronization between nodes via locking: 233 | only one Git node may work with a branch in a repository, while all others 234 | are waiting for the lock to be released. 235 | 236 | A set of [Nginx](https://www.nginx.com/) servers may act as a load balancer. 237 | A set of [HAProxy](https://www.haproxy.com/) servers may work as a load balancer for SSH traffic. 238 | 239 | ## How to contribute 240 | 241 | Read [these guidelines](https://www.yegor256.com/2014/04/15/github-guidelines.html). 242 | Make sure your build is green before you contribute 243 | your pull request. You will need to have [Ruby](https://www.ruby-lang.org/en/) 2.6+ and 244 | [Bundler](https://bundler.io/) installed. Then: 245 | 246 | ``` 247 | $ bundle update 248 | $ bundle exec rake 249 | ``` 250 | 251 | If it's clean and you don't see any error messages, submit your pull request. 252 | --------------------------------------------------------------------------------